// 共用 React 元件
const { useState, useEffect, useRef } = React;

// ── Icons ─────────────────────────────────────────────────────────────────────
const Icon = {
  Edit: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M11.5 2.5l2 2L5 13H3v-2L11.5 2.5z" />
    </svg>
  ),
  ArrowRight: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 8h10M9 4l4 4-4 4" />
    </svg>
  ),
  Undo: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 8h8a3 3 0 010 6H7M3 8l3-3M3 8l3 3" />
    </svg>
  ),
  More: () => (
    <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
      <circle cx="3" cy="8" r="1.4" /><circle cx="8" cy="8" r="1.4" /><circle cx="13" cy="8" r="1.4" />
    </svg>
  ),
  Eye: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M1.5 8s2.5-4.5 6.5-4.5S14.5 8 14.5 8 12 12.5 8 12.5 1.5 8 1.5 8z" />
      <circle cx="8" cy="8" r="2" />
    </svg>
  ),
  Plus: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
      <path d="M8 3v10M3 8h10" />
    </svg>
  ),
  Check: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M3 8.5L6.5 12 13 4.5" />
    </svg>
  ),
  Trash: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M2.5 4h11M6 4V2.5h4V4M4 4l.5 9h7L12 4M6.5 7v3M9.5 7v3" />
    </svg>
  ),
  Printer: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="6" width="12" height="6" rx="1" />
      <path d="M4 6V2.5h8V6M4 12v1.5h8V12" />
      <circle cx="12" cy="8.5" r="0.5" fill="currentColor" />
    </svg>
  ),
  Warning: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <path d="M8 2l6.5 11.5h-13L8 2z" /><path d="M8 6.5v3.5M8 12v.5" />
    </svg>
  ),
  Refresh: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <path d="M13.5 8A5.5 5.5 0 112.5 5.5" /><path d="M2.5 2v3.5H6" />
    </svg>
  ),
  Table: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="2" width="12" height="12" /><path d="M2 6h12M6 6v8" />
    </svg>
  ),
  Card: () => (
    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="2" width="5" height="5" /><rect x="9" y="2" width="5" height="5" />
      <rect x="2" y="9" width="5" height="5" /><rect x="9" y="9" width="5" height="5" />
    </svg>
  ),
  Settings: () => (
    <svg width="13" height="13" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="8" cy="8" r="2.5" />
      <path d="M8 1v2M8 13v2M1 8h2M13 8h2M3.05 3.05l1.41 1.41M11.54 11.54l1.41 1.41M3.05 12.95l1.41-1.41M11.54 4.46l1.41-1.41" />
    </svg>
  ),
  Tv: () => (
    <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="1" y="3" width="14" height="9" rx="1" /><path d="M5 15h6M8 12v3" />
    </svg>
  ),
  Print: () => (
    <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
      <rect x="2" y="6" width="12" height="6" rx="1" />
      <path d="M4 6V2.5h8V6M4 12v1.5h8V12" />
    </svg>
  ),
};

// ── Status helpers ─────────────────────────────────────────────────────────────
const STATUS_LABEL = { pending: '未完成', inprogress: '製作中', done: '已完成', urgent: '緊急' };

function StatusPill({ status, manualOverride }) {
  return (
    <span className={`status-pill ${status}`} title={manualOverride ? '手動覆寫' : '自動判定'}>
      <span className="dot"></span>
      {STATUS_LABEL[status]}
      {manualOverride && <span style={{ marginLeft: 4, opacity: 0.7 }}>·手動</span>}
    </span>
  );
}

// ── Modal shell ────────────────────────────────────────────────────────────────
function Modal({ size = 'md', title, onClose, footer, children }) {
  useEffect(() => {
    const h = (e) => { if (e.key === 'Escape') onClose && onClose(); };
    window.addEventListener('keydown', h);
    return () => window.removeEventListener('keydown', h);
  }, [onClose]);

  return (
    <div className="modal-backdrop" onMouseDown={(e) => { if (e.target === e.currentTarget) onClose && onClose(); }}>
      <div className={`modal size-${size}`}>
        <div className="modal-header">
          <div className="modal-title">{title}</div>
          <button className="modal-close" onClick={onClose}>×</button>
        </div>
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-footer">{footer}</div>}
      </div>
    </div>
  );
}

// ── Editable Select ────────────────────────────────────────────────────────────
function EditableSelect({ value, options, onChange, onAddOption, onDeleteOption, placeholder = '請選擇…' }) {
  const [showManage, setShowManage] = useState(false);
  const handleChange = (e) => {
    if (e.target.value === '__ADD_NEW__') {
      const name = window.prompt('請輸入新項目名稱：');
      if (name && name.trim()) { const v = name.trim(); onAddOption(v); onChange(v); }
    } else {
      onChange(e.target.value);
    }
  };
  return (
    <div className="editable-select">
      <div className="editable-select-row">
        <select value={value || ''} onChange={handleChange}>
          {!value && <option value="" disabled>{placeholder}</option>}
          {options.map(o => <option key={o} value={o}>{o}</option>)}
          <option value="__ADD_NEW__" className="add-new">＋ 新增項目…</option>
        </select>
        {onDeleteOption && (
          <button type="button" className={`manage-opts-btn ${showManage ? 'active' : ''}`}
            onClick={() => setShowManage(m => !m)} title="管理選項清單">
            <Icon.Settings />
          </button>
        )}
      </div>
      {showManage && onDeleteOption && (
        <div className="manage-opts-panel">
          <div className="manage-opts-title">管理選項（點 × 刪除）</div>
          {options.length === 0 && <div className="manage-opts-empty">尚無自訂選項</div>}
          {options.map(o => (
            <div key={o} className="manage-opts-row">
              <span className="manage-opts-name">{o}</span>
              <button type="button" className="manage-opts-del" title="刪除此選項"
                onClick={() => { onDeleteOption(o); if (value === o) onChange(''); }}>
                ×
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Print qty input ────────────────────────────────────────────────────────────
function PrintQtyRow({ value, onChange, presets = [] }) {
  return (
    <div className="print-qty-row">
      <label htmlFor="print-qty"><Icon.Printer /> 已印刷數量</label>
      <input
        id="print-qty" type="number" min="0" value={value}
        onChange={(e) => onChange(Math.max(0, parseInt(e.target.value || '0', 10)))}
      />
      <span className="unit">份</span>
      {presets.length > 0 && (
        <div className="qty-presets">
          {presets.map(p => <button key={p} type="button" className="qty-preset" onClick={() => onChange(p)}>{p}</button>)}
        </div>
      )}
    </div>
  );
}

// ── Item cell (table) ──────────────────────────────────────────────────────────
function ItemCell({ itemKey, item, onClick }) {
  const label = window.PRODUCTION_ITEM_SHORT[itemKey];
  const isProcess = itemKey === 'process';
  const isPrintable = window.IS_PRINTABLE(itemKey);
  const notNeeded = !!item.notNeeded;
  const state = notNeeded ? 'not-needed' : (item.done ? 'done' : '');
  const tooltip = notNeeded
    ? '標記為不需製作'
    : (item.done ? `完成於 ${item.date}${isPrintable ? ` · 印刷 ${item.printQty} 份` : ''}` : `點擊標記 ${label} 完成`);
  return (
    <button className={`item-cell ${isProcess ? 'process-cell' : ''} ${state}`}
      onClick={(e) => { e.stopPropagation(); onClick(); }} title={tooltip}>
      <span className="item-cell-label">{label}</span>
      {isProcess && !notNeeded && <span className="process-value">{item.value || '—'}</span>}
      {notNeeded && <span className="item-cell-date">不需製作</span>}
      {item.done && !notNeeded && <span className="item-cell-date">{item.date}</span>}
      {item.done && !notNeeded && isPrintable && <span className="qty-chip">印 {item.printQty || 0} 份</span>}
    </button>
  );
}

// ── Confirm complete dialog ────────────────────────────────────────────────────
function ConfirmCompleteDialog({ caseItem, itemKey, onCancel, onConfirm }) {
  const today = window.todayISO();
  const [date, setDate] = useState(today);
  const isPrintable = window.IS_PRINTABLE(itemKey);
  const defaultQty = itemKey === 'calendar' ? 80 : (itemKey === 'photo' ? 2 : 1);
  const [qty, setQty] = useState(defaultQty);
  const label = window.PRODUCTION_ITEM_LABELS[itemKey];
  const presets = itemKey === 'calendar' ? [50, 80, 100, 150] : (itemKey === 'photo' ? [1, 2, 3] : [1, 2]);
  return (
    <Modal size="md" title="確認完成" onClose={onCancel}
      footer={<>
        <button className="btn-ghost" onClick={onCancel}>取消</button>
        <div style={{ flex: 1 }} />
        <button className="btn-secondary" onClick={() => onConfirm(date, isPrintable ? qty : null, { notNeeded: true })}>不需要</button>
        <button className="btn-primary" onClick={() => onConfirm(date, isPrintable ? qty : null)}>是，標記完成</button>
      </>}
    >
      <div className="confirm-msg">是否確定<strong>「{label}」</strong>已完成?</div>
      <dl className="confirm-meta">
        <dt>案件編號</dt><dd className="mono">{caseItem.id}</dd>
        <dt>案名</dt><dd>{caseItem.name}</dd>
        <dt>禮儀師</dt><dd>{caseItem.director}</dd>
        <dt>告別式</dt><dd className="mono">{caseItem.funeralDate}</dd>
      </dl>
      <div className="date-editor">
        <label htmlFor="completion-date">完成日期</label>
        <input id="completion-date" className="tb-input" type="date" value={date}
          onChange={(e) => setDate(e.target.value)} style={{ minWidth: 160 }} />
      </div>
      {isPrintable && <PrintQtyRow value={qty} onChange={setQty} presets={presets} />}
    </Modal>
  );
}

// ── Process picker dialog ──────────────────────────────────────────────────────
function ProcessPickerDialog({ caseItem, onCancel, onConfirm }) {
  const today = window.todayISO();
  const existing = caseItem.items.process;

  const getInitialMode = () =>
    (existing.value === '合一' || existing.value === '致謝+流程') ? 'print' : 'tv';
  const getInitialSub = () =>
    existing.value === '致謝+流程' ? '致謝+流程' : '合一';

  const [mode, setMode] = useState(getInitialMode());
  const [printSub, setPrintSub] = useState(getInitialSub());
  const [date, setDate] = useState(today);
  const [qty, setQty] = useState(existing.printQty || 1);

  const isPrint = mode === 'print';
  const finalValue = isPrint ? printSub : '小電視';

  return (
    <Modal size="md" title="流程 — 選擇製作類型" onClose={onCancel}
      footer={<>
        <button className="btn-ghost" onClick={onCancel}>取消</button>
        <div style={{ flex: 1 }} />
        <button className="btn-secondary" onClick={() => onConfirm(null, date, 0, { notNeeded: true })}>不需要</button>
        <button className="btn-primary" onClick={() => onConfirm(finalValue, date, isPrint ? qty : 0)}>標記完成</button>
      </>}
    >
      <div className="process-type-selector">
        <button type="button" className={`process-type-btn ${mode === 'tv' ? 'selected' : ''}`}
          onClick={() => setMode('tv')}>
          <span className="ptb-icon"><Icon.Tv /></span>
          <span className="ptb-label">小電視</span>
          <span className="ptb-desc">電視螢幕播放</span>
        </button>
        <button type="button" className={`process-type-btn ${mode === 'print' ? 'selected' : ''}`}
          onClick={() => setMode('print')}>
          <span className="ptb-icon"><Icon.Print /></span>
          <span className="ptb-label">印刷</span>
          <span className="ptb-desc">紙本印製流程表</span>
        </button>
      </div>

      {isPrint && (
        <div className="process-print-sub">
          <div className="process-sub-title">印刷類型</div>
          <div className="process-options">
            {['合一', '致謝+流程'].map(opt => (
              <button key={opt} type="button" className={`process-option ${printSub === opt ? 'selected' : ''}`}
                onClick={() => setPrintSub(opt)}>{opt}</button>
            ))}
          </div>
        </div>
      )}

      <div className="date-editor" style={{ marginTop: 16 }}>
        <label htmlFor="process-date">完成日期</label>
        <input id="process-date" className="tb-input" type="date" value={date}
          onChange={(e) => setDate(e.target.value)} style={{ minWidth: 160 }} />
      </div>
      {isPrint && <PrintQtyRow value={qty} onChange={setQty} presets={[1, 2]} />}
    </Modal>
  );
}

// ── Edit date dialog ───────────────────────────────────────────────────────────
function EditDateDialog({ caseItem, itemKey, onCancel, onSave, onUndo, onToggleNotNeeded }) {
  const item = caseItem.items[itemKey];
  const [date, setDate] = useState(item.date || window.todayISO());
  const isPrintable = window.IS_PRINTABLE(itemKey);
  const [qty, setQty] = useState(item.printQty || 0);
  const label = window.PRODUCTION_ITEM_LABELS[itemKey];
  const notNeeded = !!item.notNeeded;
  const presets = itemKey === 'calendar' ? [50, 80, 100, 150] : (itemKey === 'photo' ? [1, 2, 3] : [1, 2]);
  return (
    <Modal size="md" title={`編輯「${label}」`} onClose={onCancel}
      footer={<>
        <button className="btn-ghost" onClick={onUndo}>還原為未完成</button>
        <div style={{ flex: 1 }} />
        <button className="btn-ghost" onClick={onCancel}>取消</button>
        {!notNeeded && <button className="btn-primary" onClick={() => onSave(date, isPrintable ? qty : null)}>儲存</button>}
      </>}
    >
      <div className="confirm-msg">
        <strong>{caseItem.name}</strong> · 「{label}」
        目前標記為 {notNeeded ? <em style={{ color: 'var(--text-soft)' }}>不需製作</em> : <em style={{ color: 'var(--status-done)' }}>已完成</em>}。
      </div>
      <div style={{ marginTop: 12, padding: 10, background: 'var(--surface-muted)', border: '1px solid var(--border)' }}>
        <button className="btn-secondary" style={{ width: '100%', justifyContent: 'center' }}
          onClick={() => onToggleNotNeeded()}>
          {notNeeded ? '改為「已完成（有製作）」' : '改為「不需要（不需製作）」'}
        </button>
      </div>
      {!notNeeded && (<>
        <div className="date-editor">
          <label htmlFor="edit-date">完成日期</label>
          <input id="edit-date" className="tb-input" type="date" value={date || ''}
            onChange={(e) => setDate(e.target.value)} style={{ minWidth: 160 }} />
        </div>
        {isPrintable && <PrintQtyRow value={qty} onChange={setQty} presets={presets} />}
      </>)}
    </Modal>
  );
}

// ── Context menu ───────────────────────────────────────────────────────────────
function ContextMenu({ x, y, caseItem, onAction, onClose }) {
  const ref = useRef();
  useEffect(() => {
    const h = (e) => { if (ref.current && !ref.current.contains(e.target)) onClose(); };
    document.addEventListener('mousedown', h);
    return () => document.removeEventListener('mousedown', h);
  }, [onClose]);

  const adjX = Math.min(x, window.innerWidth - 220);
  const adjY = Math.min(y, window.innerHeight - 280);
  const status = window.effectiveStatus(caseItem);

  return (
    <div className="context-menu" ref={ref} style={{ left: adjX, top: adjY }}>
      <div className="ctx-section-label">案件 {caseItem.id}</div>
      <button className="ctx-item" onClick={() => onAction('open')}>
        <span className="ctx-icon"><Icon.Eye /></span>檢視 / 編輯
      </button>
      <div className="ctx-divider" />
      <div className="ctx-section-label">變更狀態</div>
      {status !== 'pending' && (
        <button className="ctx-item" onClick={() => onAction('setPending')}>
          <span className="ctx-icon"><Icon.Undo /></span>還原為「未完成」
        </button>
      )}
      {status !== 'inprogress' && (
        <button className="ctx-item" onClick={() => onAction('setInProgress')}>
          <span className="ctx-icon"><Icon.Edit /></span>移至「製作中」
        </button>
      )}
      {status !== 'done' && (
        <button className="ctx-item" onClick={() => onAction('setDone')}>
          <span className="ctx-icon"><Icon.ArrowRight /></span>移至「已完成」
        </button>
      )}
      {caseItem.manualStatus && (
        <button className="ctx-item" onClick={() => onAction('clearManual')}>
          <span className="ctx-icon"><Icon.Undo /></span>清除手動覆寫
        </button>
      )}
      <div className="ctx-divider" />
      <button className="ctx-item danger" onClick={() => onAction('delete')}>
        <span className="ctx-icon"><Icon.Trash /></span>刪除案件
      </button>
    </div>
  );
}

// ── Conflict modal ─────────────────────────────────────────────────────────────
function ConflictModal({ caseName, onReload, onCancel }) {
  return (
    <Modal size="md"
      title={<><span style={{ color: 'var(--status-urgent)' }}><Icon.Warning /></span>&nbsp;資料衝突</>}
      onClose={onCancel}
      footer={<>
        <button className="btn-ghost" onClick={onCancel}>取消（保留原視窗）</button>
        <button className="btn-primary" onClick={onReload}>重新載入最新資料</button>
      </>}
    >
      <div className="conflict-banner" style={{ marginBottom: 0 }}>
        <strong>⚠ 此案件已被其他使用者修改</strong><br />
        「{caseName}」在您編輯期間已被更新。
      </div>
      <div style={{ marginTop: 16, fontSize: 13.5, color: 'var(--text-mid)', lineHeight: 1.7 }}>
        點擊「重新載入」可取得最新版本，<br />
        您未儲存的變更將會遺失。
      </div>
    </Modal>
  );
}

Object.assign(window, {
  Icon, StatusPill, Modal, ItemCell,
  ConfirmCompleteDialog, ProcessPickerDialog, EditDateDialog,
  ContextMenu, ConflictModal,
  STATUS_LABEL, EditableSelect, PrintQtyRow,
});

