// 企劃部案件管理系統 — Main App
const { useState: useS, useEffect: useE, useMemo, useRef: useR } = React;

// ── 登入畫面 ───────────────────────────────────────────────────────────────────
function LoginScreen({ onLogin }) {
  const [pw, setPw] = useS('');
  const [err, setErr] = useS('');
  const [loading, setLoading] = useS(false);

  const handleSubmit = async (e) => {
    e.preventDefault();
    if (!pw.trim()) return;
    setLoading(true);
    setErr('');
    sessionStorage.setItem('auth_token', pw.trim());
    try {
      await window.api.getCases();
      onLogin();
    } catch (ex) {
      sessionStorage.removeItem('auth_token');
      setErr(ex.code === 401 ? '密碼錯誤，請重試' : '連線失敗：' + ex.message);
      setLoading(false);
    }
  };

  return (
    <div className="login-screen">
      <div className="login-box">
        <div className="login-header">
          <h1>企劃部案件管理系統</h1>
          <span className="dept-tag">PLANNING</span>
        </div>
        <p className="login-sub">追蹤案件製作進度 · 靈前照 / 靈前影片 / 流程（小電視） / 年曆</p>
        <form onSubmit={handleSubmit} className="login-form">
          <label htmlFor="login-pw">存取密碼</label>
          <input
            id="login-pw" type="password" placeholder="請輸入密碼"
            value={pw} autoFocus autoComplete="current-password"
            onChange={(e) => { setPw(e.target.value); setErr(''); }}
          />
          {err && <div className="login-err">{err}</div>}
          <button type="submit" className="btn-primary" disabled={loading}>
            {loading ? '驗證中…' : '進入系統'}
          </button>
        </form>
      </div>
    </div>
  );
}

// ── Toast 通知 ────────────────────────────────────────────────────────────────
function Toast({ toast, onDismiss }) {
  useE(() => {
    if (!toast) return;
    const t = setTimeout(onDismiss, 4000);
    return () => clearTimeout(t);
  }, [toast]);
  if (!toast) return null;
  return (
    <div className={`toast toast-${toast.type}`}>
      {toast.message}
      <button onClick={onDismiss}>×</button>
    </div>
  );
}

// ── Main App ──────────────────────────────────────────────────────────────────
function App() {
  const [authed, setAuthed] = useS(() => !!sessionStorage.getItem('auth_token'));

  // Data
  const [cases, setCases] = useS([]);
  const [memorialLocations, setMemorialLocations] = useS([]);
  const [funeralLocations, setFuneralLocations] = useS([]);
  const [directors, setDirectors] = useS([]);
  const [loading, setLoading] = useS(true);
  const [layout, setLayout] = useS('table');

  // Filter
  const [filterYear, setFilterYear] = useS('all');
  const [filterMonth, setFilterMonth] = useS('all');
  const [searchName, setSearchName] = useS('');
  const [searchDirector, setSearchDirector] = useS('all');
  const [statusFilter, setStatusFilter] = useS(null);

  // Print stats filter
  const [psYear, setPsYear] = useS('all');
  const [psMonth, setPsMonth] = useS('all');

  // Modals
  const [confirmDlg, setConfirmDlg] = useS(null);
  const [editDateDlg, setEditDateDlg] = useS(null);
  const [detailCaseId, setDetailCaseId] = useS(null);
  const [statusModalKey, setStatusModalKey] = useS(null);
  const [ctxMenu, setCtxMenu] = useS(null);
  const [conflictData, setConflictData] = useS(null); // { caseId, latest }
  const [saving, setSaving] = useS(false);

  // Toast
  const [toast, setToast] = useS(null);
  const showToast = (message, type = 'info') => setToast({ message, type });

  // ── Data loading ───────────────────────────────────────────────────────────
  const loadData = async () => {
    try {
      const [casesData, opts] = await Promise.all([
        window.api.getCases(),
        window.api.getOptions(),
      ]);
      setCases(casesData);
      if (opts.memorial_location?.length) setMemorialLocations(opts.memorial_location);
      if (opts.funeral_location?.length) setFuneralLocations(opts.funeral_location);
      if (opts.director?.length) setDirectors(opts.director);
    } catch (ex) {
      if (ex.code === 401) { sessionStorage.removeItem('auth_token'); setAuthed(false); }
      else showToast('載入失敗：' + ex.message, 'error');
    } finally {
      setLoading(false);
    }
  };

  useE(() => {
    if (!authed) return;
    loadData();
    // Auto-refresh every 30 seconds
    const interval = setInterval(loadData, 30000);
    return () => clearInterval(interval);
  }, [authed]);

  const addOption = async (kind, value) => {
    const setter = { memorial_location: setMemorialLocations, funeral_location: setFuneralLocations, director: setDirectors }[kind];
    setter && setter(prev => prev.includes(value) ? prev : [...prev, value]);
    await window.api.addOption(kind, value).catch(() => {});
  };

  const deleteOption = async (kind, value) => {
    const setter = { memorial_location: setMemorialLocations, funeral_location: setFuneralLocations, director: setDirectors }[kind];
    setter && setter(prev => prev.filter(v => v !== value));
    await window.api.deleteOption(kind, value).catch(() => {});
  };

  // ── Derived ────────────────────────────────────────────────────────────────
  const counts = useMemo(() => {
    const c = { pending: 0, inprogress: 0, done: 0 };
    cases.forEach(cs => { c[window.effectiveStatus(cs)]++; });
    return c;
  }, [cases]);

  const urgentCount = useMemo(() => cases.filter(c => window.isUrgent(c)).length, [cases]);

  const availableYears = useMemo(() => {
    const s = new Set(cases.map(c => c.date.slice(0, 4)));
    return [...s].sort().reverse();
  }, [cases]);

  const filtered = useMemo(() => cases.filter(c => {
    if (filterYear !== 'all' && c.date.slice(0, 4) !== filterYear) return false;
    if (filterMonth !== 'all' && c.date.slice(5, 7) !== filterMonth) return false;
    if (searchName && !c.name.toLowerCase().includes(searchName.toLowerCase())) return false;
    if (searchDirector !== 'all' && c.director !== searchDirector) return false;
    if (statusFilter && window.effectiveStatus(c) !== statusFilter) return false;
    return true;
  }).sort((a, b) => b.date.localeCompare(a.date)), [cases, filterYear, filterMonth, searchName, searchDirector, statusFilter]);

  // ── Mutations ──────────────────────────────────────────────────────────────
  const updateLocalCase = (id, mutator) => {
    setCases(prev => prev.map(c => c.id === id ? mutator({ ...c, items: { ...c.items } }) : c));
  };

  const saveCase = async (updated) => {
    setSaving(true);
    try {
      const result = await window.api.updateCase(updated.id, updated);
      setCases(prev => prev.map(c => c.id === updated.id ? { ...updated, version: result.version } : c));
      showToast('已儲存', 'success');
    } catch (ex) {
      if (ex.code === 409) {
        setConflictData({ caseId: updated.id, latest: ex.latest, caseName: updated.name });
        setCases(prev => prev.map(c => c.id === updated.id ? ex.latest : c));
      } else {
        showToast('儲存失敗：' + ex.message, 'error');
      }
    } finally {
      setSaving(false);
    }
  };

  const markItemDone = async (id, itemKey, date, opts = {}) => {
    const mutator = (c) => {
      const cur = c.items[itemKey];
      const item = { ...cur, done: true, date, notNeeded: !!opts.notNeeded };
      if (opts.notNeeded) {
        item.date = window.todayISO();
        if (window.IS_PRINTABLE(itemKey)) item.printQty = 0;
      } else {
        if (itemKey === 'process' && opts.value) item.value = opts.value;
        if (window.IS_PRINTABLE(itemKey) && opts.printQty != null) item.printQty = opts.printQty;
      }
      c.items[itemKey] = item;
      return c;
    };
    updateLocalCase(id, mutator);
    const updated = mutator({ ...cases.find(c => c.id === id), items: { ...cases.find(c => c.id === id).items } });
    await saveCase(updated);
  };

  const toggleNotNeeded = async (id, itemKey) => {
    const c = cases.find(c => c.id === id);
    const cur = c.items[itemKey];
    const mutator = (c) => {
      if (cur.notNeeded) {
        c.items[itemKey] = { ...cur, notNeeded: false };
      } else {
        c.items[itemKey] = { ...cur, done: true, notNeeded: true, date: window.todayISO(), ...(window.IS_PRINTABLE(itemKey) ? { printQty: 0 } : {}) };
      }
      return c;
    };
    updateLocalCase(id, mutator);
    const updated = mutator({ ...c, items: { ...c.items } });
    await saveCase(updated);
  };

  const updateItemDetails = async (id, itemKey, date, printQty) => {
    const mutator = (c) => {
      const item = { ...c.items[itemKey], date };
      if (window.IS_PRINTABLE(itemKey) && printQty != null) item.printQty = printQty;
      c.items[itemKey] = item;
      return c;
    };
    updateLocalCase(id, mutator);
    const updated = mutator({ ...cases.find(c => c.id === id), items: { ...cases.find(c => c.id === id).items } });
    await saveCase(updated);
  };

  const undoItem = async (id, itemKey) => {
    const mutator = (c) => {
      const reset = { ...c.items[itemKey], done: false, date: null, notNeeded: false };
      if (window.IS_PRINTABLE(itemKey)) reset.printQty = 0;
      c.items[itemKey] = reset;
      return c;
    };
    updateLocalCase(id, mutator);
    const updated = mutator({ ...cases.find(c => c.id === id), items: { ...cases.find(c => c.id === id).items } });
    await saveCase(updated);
  };

  const setManualStatus = async (id, status) => {
    setCases(prev => prev.map(c => c.id === id ? { ...c, manualStatus: status } : c));
    const updated = { ...cases.find(c => c.id === id), manualStatus: status };
    await saveCase(updated);
  };

  const clearManualStatus = async (id) => {
    setCases(prev => prev.map(c => c.id === id ? { ...c, manualStatus: null } : c));
    const updated = { ...cases.find(c => c.id === id), manualStatus: null };
    await saveCase(updated);
  };

  const deleteCase = async (id) => {
    if (!confirm('確定要刪除這筆案件嗎?')) return;
    setCases(prev => prev.filter(c => c.id !== id));
    try {
      await window.api.deleteCase(id);
      showToast('案件已刪除', 'info');
    } catch (ex) {
      showToast('刪除失敗：' + ex.message, 'error');
      loadData();
    }
  };

  const handleAddCase = async () => {
    const today = window.todayISO();
    const nextNum = String(cases.length + 119).padStart(4, '0');
    const newId = `C-${today.slice(0, 4)}-${nextNum}`;
    const newCase = {
      id: newId, date: today, name: '（新案件 — 待填寫）',
      memorialLocation: memorialLocations[0] || '', director: directors[0] || '',
      funeralDate: today, funeralLocation: funeralLocations[0] || '',
      items: {
        photo:    { done: false, date: null, printQty: 0, notNeeded: false },
        video:    { done: false, date: null, notNeeded: false },
        process:  { done: false, date: null, value: null, printQty: 0, notNeeded: false },
        calendar: { done: false, date: null, printQty: 0, notNeeded: false },
      },
      manualStatus: null, version: 1,
    };
    setCases(prev => [newCase, ...prev]);
    setDetailCaseId(newId);
    try {
      await window.api.createCase(newCase);
    } catch (ex) {
      showToast('新增失敗：' + ex.message, 'error');
      setCases(prev => prev.filter(c => c.id !== newId));
    }
  };

  const getCase = (id) => cases.find(c => c.id === id);

  const handleCtxAction = (action) => {
    const id = ctxMenu.caseId;
    setCtxMenu(null);
    switch (action) {
      case 'open':         setDetailCaseId(id); break;
      case 'setPending':   setManualStatus(id, 'pending'); break;
      case 'setInProgress':setManualStatus(id, 'inprogress'); break;
      case 'setDone':      setManualStatus(id, 'done'); break;
      case 'clearManual':  clearManualStatus(id); break;
      case 'delete':       deleteCase(id); break;
    }
  };

  const handleItemClick = (caseId, itemKey) => {
    setConfirmDlg({ caseId, itemKey, mode: itemKey === 'process' ? 'process' : 'confirm' });
  };
  const handleItemEdit = (caseId, itemKey) => setEditDateDlg({ caseId, itemKey });

  const todayStr = window.todayISO();
  const showUrgent = urgentCount > 0;

  if (!authed) return <LoginScreen onLogin={() => setAuthed(true)} />;

  if (loading) {
    return (
      <div className="loading-screen">
        <div className="loading-spinner"></div>
        <div>載入中…</div>
      </div>
    );
  }

  return (
    <div className="app-shell">
      {/* Header */}
      <header className="app-header">
        <div>
          <div className="app-title">
            <h1>企劃部案件管理系統</h1>
            <span className="dept-tag">PLANNING</span>
          </div>
          <p className="app-subtitle">追蹤案件製作進度 · 靈前照 / 靈前影片 / 流程（小電視） / 年曆</p>
        </div>
        <div className="app-header-meta">
          <span className="today">今日 {todayStr}</span>
          <button className="btn-ghost" onClick={handleAddCase}>
            <window.Icon.Plus /> &nbsp;新增案件
          </button>
        </div>
      </header>

      {/* Status grid */}
      <div className={`status-grid ${showUrgent ? 'has-urgent' : ''}`}>
        {showUrgent && (
          <button className="status-card urgent" onClick={() => setStatusModalKey('urgent')}>
            <div className="status-strip"></div>
            <span className="urgent-pulse"></span>
            <div className="status-label"><span className="status-dot"></span>緊急未完成</div>
            <div className="status-count">{urgentCount}<span className="unit">件</span></div>
            <div className="status-meta">
              <span>告別式 &lt; 2 天且未完成</span>
              <span className="view-link">立即處理 →</span>
            </div>
          </button>
        )}
        {[
          { key: 'pending',    title: '未完成', desc: '尚未開始任何製作項目' },
          { key: 'inprogress', title: '製作中', desc: '部分項目已完成' },
          { key: 'done',       title: '已完成', desc: '全部項目皆已完成' },
        ].map(s => (
          <button key={s.key} className={`status-card ${s.key}`} onClick={() => setStatusModalKey(s.key)}>
            <div className="status-strip"></div>
            <div className="status-label"><span className="status-dot"></span>{s.title}</div>
            <div className="status-count">{counts[s.key]}<span className="unit">件</span></div>
            <div className="status-meta">
              <span>{s.desc}</span><span className="view-link">檢視明細 →</span>
            </div>
          </button>
        ))}
      </div>

      {/* Print stats */}
      <window.PrintStatsCard
        cases={cases} year={psYear} month={psMonth}
        onChangeYear={setPsYear} onChangeMonth={setPsMonth} availableYears={availableYears}
      />

      {/* Toolbar */}
      <div className="toolbar">
        <div className="toolbar-group">
          <label>年份</label>
          <select className="tb-select" value={filterYear} onChange={(e) => setFilterYear(e.target.value)}>
            <option value="all">全部</option>
            {availableYears.map(y => <option key={y} value={y}>{y}</option>)}
          </select>
        </div>
        <div className="toolbar-group">
          <label>月份</label>
          <select className="tb-select" value={filterMonth} onChange={(e) => setFilterMonth(e.target.value)}>
            <option value="all">全部</option>
            {Array.from({ length: 12 }, (_, i) => String(i + 1).padStart(2, '0')).map(m => (
              <option key={m} value={m}>{parseInt(m, 10)} 月</option>
            ))}
          </select>
        </div>
        <div className="toolbar-divider"></div>
        <div className="toolbar-group">
          <input className="tb-input search" type="text" placeholder="搜尋案名…"
            value={searchName} onChange={(e) => setSearchName(e.target.value)} style={{ minWidth: 200 }} />
        </div>
        <div className="toolbar-group">
          <label>禮儀師</label>
          <select className="tb-select" value={searchDirector} onChange={(e) => setSearchDirector(e.target.value)}>
            <option value="all">全部</option>
            {directors.map(d => <option key={d} value={d}>{d}</option>)}
          </select>
        </div>
        {statusFilter && (
          <span className="status-chip">
            狀態 · {window.STATUS_LABEL[statusFilter]}
            <button onClick={() => setStatusFilter(null)} title="清除">×</button>
          </span>
        )}
        <div className="toolbar-spacer"></div>
        <span className="result-count">共 {filtered.length} / {cases.length} 筆</span>
        {(filterYear !== 'all' || filterMonth !== 'all' || searchName || searchDirector !== 'all' || statusFilter) && (
          <button className="btn-text" onClick={() => {
            setFilterYear('all'); setFilterMonth('all');
            setSearchName(''); setSearchDirector('all'); setStatusFilter(null);
          }}>清除篩選</button>
        )}
        <div className="toolbar-divider"></div>
        <div className="toolbar-group" style={{ gap: 4 }}>
          <button className={`layout-btn ${layout === 'table' ? 'active' : ''}`} onClick={() => setLayout('table')} title="表格模式">
            <window.Icon.Table />
          </button>
          <button className={`layout-btn ${layout === 'card' ? 'active' : ''}`} onClick={() => setLayout('card')} title="卡片模式">
            <window.Icon.Card />
          </button>
        </div>
        <button className="layout-btn" onClick={loadData} title="重新整理"><window.Icon.Refresh /></button>
      </div>

      {/* Case list */}
      {filtered.length === 0 ? (
        <div className="case-list">
          <div className="empty-state">
            <div className="icon">∅</div>
            <div>沒有符合條件的案件</div>
            <div style={{ marginTop: 8, fontSize: 12 }}>試著調整篩選條件，或新增一筆案件</div>
          </div>
        </div>
      ) : layout === 'card' ? (
        <div className="case-cards">
          {filtered.map(c => (
            <window.CaseCard key={c.id} caseItem={c}
              onContextMenu={(x, y, id) => setCtxMenu({ x, y, caseId: id })}
              onOpen={(id) => setDetailCaseId(id)}
              onItemClick={handleItemClick} onItemEdit={handleItemEdit} />
          ))}
        </div>
      ) : (
        <div className="case-list">
          <table className="case-table">
            <thead>
              <tr>
                <th>日期</th><th>案名</th><th>豎靈地點</th><th>禮儀師</th>
                <th>告別式日期</th><th>告別式地點</th>
                <th>靈前照</th><th>靈前影片</th><th>流程</th><th>年曆</th>
                <th>狀態</th><th style={{ width: 50 }}></th>
              </tr>
            </thead>
            <tbody>
              {filtered.map(c => (
                <window.CaseRow key={c.id} caseItem={c}
                  onContextMenu={(x, y, id) => setCtxMenu({ x, y, caseId: id })}
                  onOpen={(id) => setDetailCaseId(id)}
                  onItemClick={handleItemClick} onItemEdit={handleItemEdit} />
              ))}
            </tbody>
          </table>
        </div>
      )}

      <div style={{ marginTop: 20, fontSize: 12, color: 'var(--text-faint)', textAlign: 'center' }}>
        Tip · 點擊製作欄位標記完成、印刷數量；右鍵可變更案件狀態；於詳細視窗可新增地點／禮儀師
      </div>

      {/* ── Modals ── */}

      {confirmDlg && confirmDlg.mode === 'confirm' && (() => {
        const c = getCase(confirmDlg.caseId);
        if (!c) return null;
        return (
          <window.ConfirmCompleteDialog caseItem={c} itemKey={confirmDlg.itemKey}
            onCancel={() => setConfirmDlg(null)}
            onConfirm={(date, printQty, opts = {}) => {
              markItemDone(c.id, confirmDlg.itemKey, date, { printQty, ...opts });
              setConfirmDlg(null);
            }} />
        );
      })()}

      {confirmDlg && confirmDlg.mode === 'process' && (() => {
        const c = getCase(confirmDlg.caseId);
        if (!c) return null;
        return (
          <window.ProcessPickerDialog caseItem={c}
            onCancel={() => setConfirmDlg(null)}
            onConfirm={(value, date, printQty, opts = {}) => {
              markItemDone(c.id, 'process', date, { value, printQty, ...opts });
              setConfirmDlg(null);
            }} />
        );
      })()}

      {editDateDlg && (() => {
        const c = getCase(editDateDlg.caseId);
        if (!c) return null;
        return (
          <window.EditDateDialog caseItem={c} itemKey={editDateDlg.itemKey}
            onCancel={() => setEditDateDlg(null)}
            onSave={(date, printQty) => { updateItemDetails(c.id, editDateDlg.itemKey, date, printQty); setEditDateDlg(null); }}
            onUndo={() => { undoItem(c.id, editDateDlg.itemKey); setEditDateDlg(null); }}
            onToggleNotNeeded={() => { toggleNotNeeded(c.id, editDateDlg.itemKey); setEditDateDlg(null); }} />
        );
      })()}

      {detailCaseId && (() => {
        const c = getCase(detailCaseId);
        if (!c) return null;
        return (
          <window.CaseDetailModal caseItem={c}
            onClose={() => setDetailCaseId(null)}
            onSave={async (draft) => { await saveCase(draft); setDetailCaseId(null); }}
            onItemClick={handleItemClick} onItemEdit={handleItemEdit}
            onItemNotNeeded={toggleNotNeeded}
            memorialLocations={memorialLocations} funeralLocations={funeralLocations} directors={directors}
            onAddMemorialLocation={(v) => addOption('memorial_location', v)}
            onAddFuneralLocation={(v) => addOption('funeral_location', v)}
            onAddDirector={(v) => addOption('director', v)}
            onDeleteMemorialLocation={(v) => deleteOption('memorial_location', v)}
            onDeleteFuneralLocation={(v) => deleteOption('funeral_location', v)}
            onDeleteDirector={(v) => deleteOption('director', v)}
            saving={saving} />
        );
      })()}

      {statusModalKey && (
        <window.StatusListModal status={statusModalKey} cases={cases}
          onClose={() => setStatusModalKey(null)}
          onOpenCase={(id) => setDetailCaseId(id)} />
      )}

      {ctxMenu && (() => {
        const c = getCase(ctxMenu.caseId);
        if (!c) return null;
        return (
          <window.ContextMenu x={ctxMenu.x} y={ctxMenu.y} caseItem={c}
            onAction={handleCtxAction} onClose={() => setCtxMenu(null)} />
        );
      })()}

      {conflictData && (
        <window.ConflictModal
          caseName={conflictData.caseName}
          onCancel={() => setConflictData(null)}
          onReload={() => { setConflictData(null); loadData(); }} />
      )}

      <Toast toast={toast} onDismiss={() => setToast(null)} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
