/* ============================================================
   GUI 模式 — Minecraft 介面元件編輯
   像素精準：所有繪製關閉平滑，座標取整
   ============================================================ */

const GUI_COMPONENTS = [
  { id: 'button', name: '按鈕', desc: '立體按鈕', w: 100, h: 20 },
  { id: 'panel', name: '面板', desc: '可調邊框與填充', w: 120, h: 80 },
  { id: 'slot', name: '物品槽', desc: '18×18 陰影邊框', w: 18, h: 18 },
  { id: 'icon', name: '圖示', desc: '16×16 圖示格', w: 16, h: 16 },
  { id: 'progress', name: '進度條', desc: '水平／垂直進度', w: 182, h: 5 },
  { id: 'border', name: '邊框', desc: '空心像素框', w: 64, h: 64 },
  { id: 'background', name: '背景', desc: '介面底圖', w: 0, h: 0 },
];

const MC_GUI = {
  panelFill: '#C6C6C6',
  slotFill: '#8B8B8B',
  light: '#FFFFFF',
  dark: '#555555',
  darker: '#373737',
  buttonFill: '#8B8B8B',
  progressBg: '#404040',
  progressFg: '#55FF55',
  iconFill: '#3A3A3A',
  bgFill: '#C6C6C6',
};

function createGuiWidget(type, x, y, canvasW, canvasH) {
  const def = GUI_COMPONENTS.find(c => c.id === type) || GUI_COMPONENTS[0];
  let w = def.w;
  let h = def.h;
  if (type === 'background') {
    w = canvasW;
    h = canvasH;
    x = 0;
    y = 0;
  }
  const widget = {
    id: uid(),
    type,
    name: def.name,
    x: Math.round(x),
    y: Math.round(y),
    w,
    h,
    opacity: 1,
    visible: true,
    locked: false,
    fill: type === 'slot' ? MC_GUI.slotFill
      : type === 'progress' ? MC_GUI.progressFg
      : type === 'icon' ? MC_GUI.iconFill
      : type === 'background' ? MC_GUI.bgFill
      : MC_GUI.panelFill,
    borderColor: MC_GUI.darker,
    borderWidth: type === 'panel' || type === 'border' ? 2 : (type === 'slot' || type === 'button' ? 1 : 1),
    direction: 'horizontal',
    percent: 70,
  };
  if (type === 'progress' && widget.direction === 'vertical') {
    widget.w = 5;
    widget.h = 64;
  }
  return widget;
}

function drawBezel(ctx, x, y, w, h, raised, thickness, fill) {
  ctx.fillStyle = fill;
  ctx.fillRect(x, y, w, h);
  const light = MC_GUI.light;
  const dark = MC_GUI.darker;
  const t = Math.max(1, thickness | 0);
  for (let i = 0; i < t; i++) {
    if (w - i * 2 <= 0 || h - i * 2 <= 0) break;
    ctx.fillStyle = raised ? light : dark;
    ctx.fillRect(x + i, y + i, w - i * 2, 1);
    ctx.fillRect(x + i, y + i, 1, h - i * 2);
    ctx.fillStyle = raised ? dark : light;
    ctx.fillRect(x + i, y + h - 1 - i, w - i * 2, 1);
    ctx.fillRect(x + w - 1 - i, y + i, 1, h - i * 2);
  }
}

function drawGuiWidget(ctx, wdg) {
  if (!wdg.visible) return;
  const x = wdg.x | 0;
  const y = wdg.y | 0;
  const w = Math.max(1, wdg.w | 0);
  const h = Math.max(1, wdg.h | 0);
  ctx.save();
  ctx.globalAlpha = Math.max(0, Math.min(1, wdg.opacity ?? 1));
  ctx.imageSmoothingEnabled = false;

  switch (wdg.type) {
    case 'background':
      ctx.fillStyle = wdg.fill || MC_GUI.bgFill;
      ctx.fillRect(x, y, w, h);
      break;
    case 'panel':
      drawBezel(ctx, x, y, w, h, true, wdg.borderWidth || 2, wdg.fill || MC_GUI.panelFill);
      break;
    case 'button':
      drawBezel(ctx, x, y, w, h, true, 1, wdg.fill || MC_GUI.buttonFill);
      break;
    case 'slot': {
      ctx.fillStyle = wdg.fill || MC_GUI.slotFill;
      ctx.fillRect(x, y, w, h);
      ctx.fillStyle = MC_GUI.darker;
      ctx.fillRect(x, y, w, 1);
      ctx.fillRect(x, y, 1, h);
      ctx.fillStyle = MC_GUI.light;
      ctx.fillRect(x, y + h - 1, w, 1);
      ctx.fillRect(x + w - 1, y, 1, h);
      if (w >= 4 && h >= 4) {
        ctx.fillStyle = '#00000033';
        ctx.fillRect(x + 1, y + 1, w - 2, 1);
        ctx.fillRect(x + 1, y + 1, 1, h - 2);
      }
      break;
    }
    case 'icon':
      drawBezel(ctx, x, y, w, h, false, 1, wdg.fill || MC_GUI.iconFill);
      break;
    case 'progress': {
      ctx.fillStyle = MC_GUI.progressBg;
      ctx.fillRect(x, y, w, h);
      const pct = Math.max(0, Math.min(100, Number(wdg.percent) || 0)) / 100;
      ctx.fillStyle = wdg.fill || MC_GUI.progressFg;
      if (wdg.direction === 'vertical') {
        const fh = Math.round(h * pct);
        ctx.fillRect(x, y + (h - fh), w, fh);
      } else {
        ctx.fillRect(x, y, Math.round(w * pct), h);
      }
      ctx.fillStyle = MC_GUI.darker;
      ctx.fillRect(x, y, w, 1);
      ctx.fillRect(x, y, 1, h);
      ctx.fillStyle = MC_GUI.light;
      ctx.fillRect(x, y + h - 1, w, 1);
      ctx.fillRect(x + w - 1, y, 1, h);
      break;
    }
    case 'border': {
      const bw = Math.max(1, wdg.borderWidth || 1);
      ctx.fillStyle = wdg.borderColor || MC_GUI.darker;
      ctx.fillRect(x, y, w, bw);
      ctx.fillRect(x, y + h - bw, w, bw);
      ctx.fillRect(x, y, bw, h);
      ctx.fillRect(x + w - bw, y, bw, h);
      break;
    }
    default:
      ctx.fillStyle = wdg.fill || '#888';
      ctx.fillRect(x, y, w, h);
  }
  ctx.restore();
}

function drawGuiWidgets(ctx, widgets, selectedId, canvasW, canvasH) {
  ctx.imageSmoothingEnabled = false;
  ctx.clearRect(0, 0, canvasW, canvasH);
  (widgets || []).forEach(w => drawGuiWidget(ctx, w));
  const sel = (widgets || []).find(w => w.id === selectedId);
  if (sel && sel.visible) {
    ctx.save();
    ctx.strokeStyle = '#5cb85c';
    ctx.lineWidth = 1;
    ctx.setLineDash([]);
    ctx.strokeRect(sel.x + 0.5, sel.y + 0.5, sel.w - 1, sel.h - 1);
    const handles = guiHandlePoints(sel);
    ctx.fillStyle = '#5cb85c';
    handles.forEach(p => {
      ctx.fillRect(p.x - 1, p.y - 1, 3, 3);
    });
    ctx.restore();
  }
}

function guiHandlePoints(wdg) {
  const x = wdg.x;
  const y = wdg.y;
  const r = wdg.x + wdg.w;
  const b = wdg.y + wdg.h;
  const cx = wdg.x + (wdg.w >> 1);
  const cy = wdg.y + (wdg.h >> 1);
  return [
    { id: 'nw', x, y },
    { id: 'n', x: cx, y },
    { id: 'ne', x: r, y },
    { id: 'e', x: r, y: cy },
    { id: 'se', x: r, y: b },
    { id: 's', x: cx, y: b },
    { id: 'sw', x, y: b },
    { id: 'w', x, y: cy },
  ];
}

function hitTestHandle(wdg, px, py, zoom) {
  const tol = Math.max(2, Math.round(6 / Math.max(1, zoom)));
  const handles = guiHandlePoints(wdg);
  for (let i = 0; i < handles.length; i++) {
    const h = handles[i];
    if (Math.abs(px - h.x) <= tol && Math.abs(py - h.y) <= tol) return h.id;
  }
  return null;
}

function hitTestWidget(widgets, px, py) {
  for (let i = widgets.length - 1; i >= 0; i--) {
    const w = widgets[i];
    if (!w.visible) continue;
    if (px >= w.x && py >= w.y && px < w.x + w.w && py < w.y + w.h) return w;
  }
  return null;
}

function applyGuiResize(wdg, handle, px, py, canvasW, canvasH) {
  let x1 = wdg.x;
  let y1 = wdg.y;
  let x2 = wdg.x + wdg.w;
  let y2 = wdg.y + wdg.h;
  if (handle === 'n' || handle === 'ne' || handle === 'nw') y1 = py;
  if (handle === 's' || handle === 'se' || handle === 'sw') y2 = py;
  if (handle === 'w' || handle === 'nw' || handle === 'sw') x1 = px;
  if (handle === 'e' || handle === 'ne' || handle === 'se') x2 = px;
  let nx = Math.round(Math.min(x1, x2));
  let ny = Math.round(Math.min(y1, y2));
  let nw = Math.max(1, Math.abs(Math.round(x2) - Math.round(x1)));
  let nh = Math.max(1, Math.abs(Math.round(y2) - Math.round(y1)));
  if (wdg.type === 'slot') {
    nw = Math.max(8, nw);
    nh = Math.max(8, nh);
  }
  nx = Math.max(0, Math.min(nx, canvasW - 1));
  ny = Math.max(0, Math.min(ny, canvasH - 1));
  nw = Math.min(nw, canvasW - nx);
  nh = Math.min(nh, canvasH - ny);
  return { ...wdg, x: nx, y: ny, w: nw, h: nh };
}

function alignGuiWidget(wdg, dir, canvasW, canvasH) {
  const next = { ...wdg };
  if (dir === 'left') next.x = 0;
  if (dir === 'center') next.x = Math.round((canvasW - wdg.w) / 2);
  if (dir === 'right') next.x = canvasW - wdg.w;
  if (dir === 'top') next.y = 0;
  if (dir === 'middle') next.y = Math.round((canvasH - wdg.h) / 2);
  if (dir === 'bottom') next.y = canvasH - wdg.h;
  next.x = Math.max(0, next.x);
  next.y = Math.max(0, next.y);
  return next;
}

function guiTypeLabel(type) {
  return (GUI_COMPONENTS.find(c => c.id === type) || {}).name || type;
}

function seedDefaultGui(canvasW, canvasH) {
  const cw = Math.max(16, canvasW | 0);
  const ch = Math.max(16, canvasH | 0);
  const widgets = [];
  widgets.push(createGuiWidget('background', 0, 0, cw, ch));
  const panelW = Math.min(176, Math.max(80, cw - 16));
  const panelH = Math.min(166, Math.max(80, ch - 16));
  const px = Math.round((cw - panelW) / 2);
  const py = Math.round((ch - panelH) / 2);
  const panel = createGuiWidget('panel', px, py, cw, ch);
  panel.w = panelW;
  panel.h = panelH;
  widgets.push(panel);
  const slot = 18;
  const gap = 2;
  const cols = Math.min(9, Math.max(1, Math.floor((panelW - 16) / (slot + gap))));
  const rows = 3;
  const gridW = cols * slot + (cols - 1) * gap;
  const startX = px + Math.round((panelW - gridW) / 2);
  const startY = py + 18;
  for (let r = 0; r < rows; r++) {
    for (let c = 0; c < cols; c++) {
      widgets.push(createGuiWidget('slot', startX + c * (slot + gap), startY + r * (slot + gap), cw, ch));
    }
  }
  const hotY = py + panelH - slot - 8;
  if (hotY > startY + rows * (slot + gap)) {
    for (let c = 0; c < cols; c++) {
      widgets.push(createGuiWidget('slot', startX + c * (slot + gap), hotY, cw, ch));
    }
  }
  return widgets;
}

function compositePixelAndGui(layers, widgets, width, height) {
  const canvas = createPixelCanvas(width, height);
  const ctx = canvas.getContext('2d');
  ctx.imageSmoothingEnabled = false;
  (layers || []).forEach(l => {
    if (!l.visible) return;
    ctx.globalAlpha = l.opacity ?? 1;
    ctx.drawImage(l.texture.canvas, 0, 0);
  });
  ctx.globalAlpha = 1;
  (widgets || []).forEach(w => drawGuiWidget(ctx, w));
  return canvas;
}

function GuiLibraryPanel({
  pendingType,
  onPick,
  selected,
  onChange,
  widgets,
  selectedId,
  onSelect,
  onReorder,
  onAlign,
  onDuplicate,
  onDelete,
  canvasW,
  canvasH,
}) {
  const previewRef = React.useRef({});

  React.useEffect(() => {
    GUI_COMPONENTS.forEach(c => {
      const el = previewRef.current[c.id];
      if (!el) return;
      const w = c.id === 'background' ? 32 : Math.min(32, c.w || 32);
      const h = c.id === 'background' ? 20 : Math.min(20, c.h || 20);
      el.width = 32;
      el.height = 20;
      const ctx = el.getContext('2d');
      ctx.imageSmoothingEnabled = false;
      ctx.clearRect(0, 0, 32, 20);
      const sample = createGuiWidget(c.id, 2, 2, 32, 20);
      sample.w = w;
      sample.h = h;
      sample.x = Math.round((32 - w) / 2);
      sample.y = Math.round((20 - h) / 2);
      drawGuiWidget(ctx, sample);
    });
  }, []);

  const moveLayer = (dir) => {
    if (!selectedId) return;
    const idx = widgets.findIndex(w => w.id === selectedId);
    if (idx < 0) return;
    const next = widgets.slice();
    const swap = idx + dir;
    if (swap < 0 || swap >= next.length) return;
    const tmp = next[idx];
    next[idx] = next[swap];
    next[swap] = tmp;
    onReorder(next);
  };

  return React.createElement('div', { className: 'panel-section' },
    React.createElement('div', { className: 'panel-section__header' },
      React.createElement('span', null, 'GUI 元件庫'),
    ),
    React.createElement('div', { className: 'panel-section__body' },
      React.createElement('div', { className: 'gui-lib-hint' },
        '拖到畫布，或點一下再點畫布放置。像素對齊，不會模糊。'
      ),
      React.createElement('div', { className: 'gui-lib-grid' },
        GUI_COMPONENTS.map(c =>
          React.createElement('div', {
            key: c.id,
            className: 'gui-lib-card' + (pendingType === c.id ? ' active' : ''),
            draggable: true,
            title: c.desc,
            onClick: () => onPick(c.id),
            onDragStart: (e) => {
              e.dataTransfer.setData('text/gui-type', c.id);
              e.dataTransfer.effectAllowed = 'copy';
            },
          },
            React.createElement('canvas', {
              className: 'gui-lib-card__preview',
              ref: (el) => { previewRef.current[c.id] = el; },
            }),
            React.createElement('div', { className: 'gui-lib-card__name' }, c.name),
            React.createElement('div', { className: 'gui-lib-card__desc' },
              c.id === 'slot' ? '18×18' : c.id === 'background' ? '滿版' : `${c.w}×${c.h}`
            ),
          )
        )
      ),

      selected && React.createElement('div', { className: 'gui-props' },
        React.createElement('div', { className: 'mc-helpers__title' }, `選取：${selected.name}`),
        React.createElement('div', { className: 'gui-prop-row' },
          React.createElement('span', null, '位置'),
          React.createElement('span', { className: 'gui-mono' }, `${selected.x}, ${selected.y}`),
        ),
        React.createElement('div', { className: 'gui-prop-row' },
          React.createElement('span', null, '尺寸'),
          React.createElement('span', { className: 'gui-mono' }, `${selected.w}×${selected.h}`),
        ),
        React.createElement('div', { className: 'slider-row' },
          React.createElement('span', { style: { fontSize: '10px', color: 'var(--text-tertiary)', width: '48px' } }, '不透明度'),
          React.createElement('input', {
            type: 'range', min: 0, max: 100, value: Math.round((selected.opacity ?? 1) * 100),
            onChange: (e) => onChange({ ...selected, opacity: parseInt(e.target.value, 10) / 100 }),
          }),
          React.createElement('span', { className: 'slider-value' }, `${Math.round((selected.opacity ?? 1) * 100)}%`),
        ),
        (selected.type === 'panel' || selected.type === 'border') && React.createElement('div', { className: 'slider-row' },
          React.createElement('span', { style: { fontSize: '10px', color: 'var(--text-tertiary)', width: '48px' } }, '邊框'),
          React.createElement('input', {
            type: 'range', min: 1, max: 8, value: selected.borderWidth || 1,
            onChange: (e) => onChange({ ...selected, borderWidth: parseInt(e.target.value, 10) }),
          }),
          React.createElement('span', { className: 'slider-value' }, `${selected.borderWidth || 1}px`),
        ),
        selected.type === 'progress' && React.createElement(React.Fragment, null,
          React.createElement('div', { className: 'mc-helpers__row' },
            React.createElement('button', {
              className: 'mc-helper-btn' + (selected.direction !== 'vertical' ? ' active' : ''),
              onClick: () => {
                const next = { ...selected, direction: 'horizontal' };
                if (selected.direction === 'vertical') {
                  next.w = selected.h;
                  next.h = selected.w;
                }
                onChange(next);
              },
            }, '水平'),
            React.createElement('button', {
              className: 'mc-helper-btn' + (selected.direction === 'vertical' ? ' active' : ''),
              onClick: () => {
                const next = { ...selected, direction: 'vertical' };
                if (selected.direction !== 'vertical') {
                  next.w = selected.h;
                  next.h = selected.w;
                }
                onChange(next);
              },
            }, '垂直'),
          ),
          React.createElement('div', { className: 'slider-row' },
            React.createElement('span', { style: { fontSize: '10px', color: 'var(--text-tertiary)', width: '48px' } }, '進度'),
            React.createElement('input', {
              type: 'range', min: 0, max: 100, value: selected.percent ?? 0,
              onChange: (e) => onChange({ ...selected, percent: parseInt(e.target.value, 10) }),
            }),
            React.createElement('span', { className: 'slider-value' }, `${selected.percent ?? 0}%`),
          ),
        ),
        React.createElement('div', { className: 'gui-prop-row' },
          React.createElement('span', null, '顏色'),
          React.createElement('input', {
            type: 'color',
            className: 'gui-color',
            value: (selected.fill || '#C6C6C6').slice(0, 7),
            onChange: (e) => onChange({ ...selected, fill: e.target.value }),
          }),
        ),
        React.createElement('div', { className: 'mc-helpers__title', style: { marginTop: 8 } }, '對齊'),
        React.createElement('div', { className: 'mc-helpers__row' },
          [['left', '左'], ['center', '中'], ['right', '右']].map(([id, label]) =>
            React.createElement('button', {
              key: id, className: 'mc-helper-btn',
              onClick: () => onAlign(id),
            }, label)
          ),
        ),
        React.createElement('div', { className: 'mc-helpers__row' },
          [['top', '上'], ['middle', '中'], ['bottom', '下']].map(([id, label]) =>
            React.createElement('button', {
              key: id, className: 'mc-helper-btn',
              onClick: () => onAlign(id),
            }, label)
          ),
        ),
        React.createElement('div', { className: 'mc-helpers__title', style: { marginTop: 8 } }, '圖層排序'),
        React.createElement('div', { className: 'mc-helpers__row' },
          React.createElement('button', { className: 'mc-helper-btn', onClick: () => moveLayer(1) }, '上移'),
          React.createElement('button', { className: 'mc-helper-btn', onClick: () => moveLayer(-1) }, '下移'),
        ),
        React.createElement('div', { className: 'mc-helpers__row', style: { marginTop: 6 } },
          React.createElement('button', { className: 'mc-helper-btn', onClick: onDuplicate, title: 'Ctrl+D' }, '複製'),
          React.createElement('button', { className: 'mc-helper-btn', onClick: onDelete, title: 'Del' }, '刪除'),
        ),
      ),

      widgets.length > 0 && React.createElement('div', { className: 'gui-layer-list' },
        React.createElement('div', { className: 'mc-helpers__title' }, '元件圖層（上＝前）'),
        widgets.slice().reverse().map(w =>
          React.createElement('div', {
            key: w.id,
            className: 'gui-layer-item' + (w.id === selectedId ? ' active' : ''),
            onClick: () => onSelect(w.id),
          },
            React.createElement('span', null, w.name),
            React.createElement('span', { className: 'gui-mono' }, `${w.w}×${w.h}`),
          )
        )
      ),
    ),
  );
}

Object.assign(window, {
  GUI_COMPONENTS,
  createGuiWidget,
  drawGuiWidgets,
  drawGuiWidget,
  hitTestHandle,
  hitTestWidget,
  applyGuiResize,
  alignGuiWidget,
  guiTypeLabel,
  seedDefaultGui,
  compositePixelAndGui,
  GuiLibraryPanel,
});
