// main.jsx — App 主程式

function seed() {
  return window.SEED_CASES.map((c) => {
    const signed = ['contract', 'schedule', 'produce', 'finance'].includes(c.stage);
    const io = window.makeIO(c);io.signed = signed;if (signed) io.signB = '果米工作室 · 多多';
    return {
      ...c,
      intentStatus: c.progress === '婉拒' ? 'declined' :
      ['contract', 'schedule', 'produce', 'finance'].includes(c.stage) ? 'accepted' :
      c.intentNature ? 'sent' : 'draft',
      intent: {
        vendor: c.vendor, product: c.product,
        nature: c.intentNature || [],
        schedule: c.schedule.online ? `${c.schedule.shoot} 拍攝 / ${c.schedule.online} 上線` : '',
        link: c.productLink, ref: ''
      },
      io,
      comm: window.makeComm(c),
      prod: window.makeProd(c),
      invoices: c.invoices || (c.invoice ? { bal: c.invoice } : {})
    };
  });
}
// PureLab 預設意願性質
window.SEED_CASES[0].intentNature = ['Reels 1 則（40–60 秒）', '限時動態 1 則（導連結・免過稿）', 'META 廣告主授權（1 個月）'];

function App() {
  const [cases, setCases] = React.useState(seed);
  const [rowIndex, setRowIndex] = React.useState({});
  const [sheetConnected, setSheetConnected] = React.useState(false);
  const [syncing, setSyncing] = React.useState(false);
  const [nav, setNav] = React.useState(() => {try {return JSON.parse(localStorage.getItem('gm_nav') || 'null') || { view: 'board', sel: null, tab: 'mail' };} catch {return { view: 'board', sel: null, tab: 'mail' };}});
  const [toastMsg, setToastMsg] = React.useState('');
  const [newOpen, setNewOpen] = React.useState(false);
  const [schedOpen, setSchedOpen] = React.useState(false);
  const [invOpen, setInvOpen] = React.useState(false);
  const [invTarget, setInvTarget] = React.useState(null);
  const [settingsOpen, setSettingsOpen] = React.useState(false);
  const tRef = React.useRef(0);

  React.useEffect(() => {try {localStorage.setItem('gm_nav', JSON.stringify(nav));} catch {}}, [nav]);

  // 報價信寄發滿 14 天未進入合約階段 → 自動將進度設為「待追蹤」
  React.useEffect(() => {
    const contractStages = ['contract','schedule','produce','finance'];
    const skipProgress = ['婉拒','未成交','結案','待追蹤'];
    setCases(cs => cs.map(c => {
      if (!c.quoteSentDate) return c;
      if (contractStages.includes(c.stage)) return c;
      if (skipProgress.includes(c.progress)) return c;
      const parts = c.quoteSentDate.split('/');
      const sentDate = new Date(+parts[0], +parts[1]-1, +parts[2]);
      const daysSince = Math.floor((Date.now() - sentDate) / 86400000);
      if (daysSince >= 14) return { ...c, progress: '待追蹤' };
      return c;
    }));
  }, []);

  // 全域 AI 設定開啟鉤子
  React.useEffect(() => { window.__openAISettings = () => setSettingsOpen(true); return () => { delete window.__openAISettings; }; }, []);
  const toast = (m) => {setToastMsg(m);clearTimeout(tRef.current);tRef.current = setTimeout(() => setToastMsg(''), 2200);};

  const doLoadFromSheet = async () => {
    try {
      const { cases: loaded, rowIndex: idx } = await window.loadCasesFromSheet();
      setCases(loaded); setRowIndex(idx); setSheetConnected(true);
      toast(`✓ 已從試算表載入 ${loaded.length} 筆案件`);
    } catch (e) { toast('載入失敗：' + e.message); }
    setSyncing(false);
  };

  const syncFromSheet = () => {
    if (!window.getSheetId?.()) { toast('尚未在 ⚙ AI 設定中填入試算表 ID'); return; }
    setSyncing(true);
    if (window.isGoogleConnected?.()) { doLoadFromSheet(); return; }
    if (!window.getGoogleClientId?.()) { toast('請先在 ⚙ AI 設定中填入 Google OAuth2 Client ID'); window.__openAISettings?.(); setSyncing(false); return; }
    window.requestGoogleToken((token, err) => {
      if (err || !token) { toast('連結 Google 失敗' + (err ? '：' + err : '')); setSyncing(false); return; }
      doLoadFromSheet();
    });
  };

  // 頁面載入時嘗試靜默重新連線：如果瀏覽器裡 Google 登入狀態還在、之前也同意過授權，
  // GIS 會直接給新權杖不跳視窗；拿不到就維持原樣，使用者再手動點「連結試算表」即可。
  React.useEffect(() => {
    if (!window.getSheetId?.() || !window.getGoogleClientId?.()) return;
    window.requestGoogleToken((token) => { if (token) doLoadFromSheet(); });
  }, []);

  const setView = (view) => setNav((n) => ({ ...n, view }));
  const openCase = (id, tab) => setNav({ view: 'detail', sel: id, tab: tab || window.currentTab(cases.find((x) => x.id === id)) });
  const setTab = (tab) => setNav((n) => ({ ...n, tab }));
  const updateCase = (id, patch) => setCases((cs) => {
    const next = cs.map((c) => c.id === id ? { ...c, ...patch } : c);
    if (sheetConnected) {
      const nc = next.find((c) => c.id === id);
      window.saveCaseToSheet(nc, rowIndex).then((res) => {
        if (res?.newRowIndex) setRowIndex((ri) => ({ ...ri, [id]: { ...(ri[id] || {}), ...res.newRowIndex } }));
      }).catch((e) => toast('寫回試算表失敗：' + e.message));
    }
    return next;
  });
  const moveCase = (id, stage) => updateCase(id, { stage });
  const setProgress = (id, value) => updateCase(id, { progress: value, willing: value === '婉拒' ? '婉拒' : cases.find((c) => c.id === id)?.willing });
  const markDeal = (id) => updateCase(id, { progress: '簽約', stage: 'contract' });
  const setPay = (id, which, patch) => {
    const c = cases.find((x) => x.id === id);
    if (c) updateCase(id, { pay: { ...c.pay, [which]: { ...c.pay[which], ...patch } } });
  };

  const sel = cases.find((c) => c.id === nav.sel);

  const createCase = ({ vendor, product, contact, kind, email }) => {
    const id = sheetConnected ? window.nextCaseId(rowIndex)
      : (vendor.replace(/[^A-Za-z\u4e00-\u9fa5]/g, '').slice(0, 2).toUpperCase() || 'NEW') + '-' + String(2400 + cases.length + 11);
    const nc = {
      id, stage: 'inquiry', vendor, product, category: window.RISK_KIND_LABEL[kind], riskKind: kind,
      contact, contactRole: '窗口', received: '2026/06/11', updated: '剛剛', avatarBg: 'var(--clay-2)',
      budgetHint: '—', value: null, email, wants: ['待確認'], productLink: '',
      risk: 'mid', riskLabel: '待評估', riskStatus: 'idle', riskFindings: null,
      quote: { items: [], situation: 's1', rush: false, groupFee: 8000, share: 15, adjusts: {} },
      schedule: { shoot: '', online: '' },
      caseType: '純業配', willing: '有興趣', progress: '洽談', deal: '洽談中', note: '',
      pay: { dep: { paid: false, date: '' }, bal: { paid: false, date: '' } },
      intentStatus: 'draft', invoices: {},
      intent: { vendor, product, nature: [], schedule: '', link: '', ref: '' }
    };
    nc.io = window.makeIO(nc);nc.comm = window.makeComm(nc);nc.prod = window.makeProd(nc);
    setCases((cs) => [nc, ...cs]);
    setNewOpen(false);
    setNav({ view: 'detail', sel: id, tab: 'mail' });
    toast('已建立案件 ' + id);
    if (sheetConnected) {
      window.appendCaseToSheet(nc, rowIndex)
        .then((res) => {
          setRowIndex((ri) => ({ ...ri, [id]: { ...(ri[id] || {}), ...(res?.rowIndex || {}) } }));
          toast('已建立案件 ' + id + '（已寫入試算表）');
        })
        .catch((e) => toast('案件已建立，但寫入試算表失敗：' + e.message));
    }
  };

  let main;
  if (nav.view === 'detail' && sel) {
    main = <window.CaseDetail c={sel} tab={nav.tab} setTab={setTab}
    onUpdate={(patch) => updateCase(sel.id, patch)} onClose={() => setView('board')}
    onMove={(st) => moveCase(sel.id, st)} onSchedule={() => setSchedOpen(true)} toast={toast} />;
  } else {
    switch (nav.view) {
      case 'law':main = <window.LawLibrary />;break;
      case 'track':main = <window.TrackingView cases={cases} onOpen={openCase} onSetProgress={setProgress} onSetNote={(id,v)=>updateCase(id,{note:v})} />;break;
      case 'docs':main = <window.DocsView cases={cases} onOpen={openCase} />;break;
      case 'contract':main = <window.ContractView cases={cases} onOpen={openCase} />;break;
      case 'cal':main = <window.CalView cases={cases} toast={toast} />;break;
      case 'pay':main = <window.PayView cases={cases} onOpen={openCase} onSetPay={setPay} onSetProgress={setProgress} onOpenInvoice={(c, seg) => {setInvTarget({ c, seg });setInvOpen(true);}} toast={toast} />;break;
      case 'invoice':main = <window.InvoiceView cases={cases} onOpen={openCase} onOpenInvoice={(c, seg) => {setInvTarget({ c, seg });setInvOpen(true);}} />;break;
      case 'report':main = <window.ReportView cases={cases} onOpen={openCase} toast={toast} />;break;
      default:main = <window.Board cases={cases} onOpen={openCase} onNavPay={()=>setNav(n=>({...n,view:'pay'}))} onNew={() => setNewOpen(true)}
        onSyncSheet={syncFromSheet} syncing={syncing} sheetConnected={sheetConnected} onMarkDeal={markDeal} />;
    }
  }

  const activeNav = nav.view === 'detail' ? 'board' : nav.view;
  return (
    <div className="app">
      <window.Sidebar active={activeNav} onNav={setView} onOpenSettings={()=>setSettingsOpen(true)} />
      {main}
      <window.NewCaseModal open={newOpen} onClose={() => setNewOpen(false)} onCreate={createCase} />
      <window.ScheduleModal open={schedOpen} onClose={() => setSchedOpen(false)} c={sel}
      onSave={(s) => updateCase(sel.id, { schedule: s })} toast={toast} />
      <window.InvoiceModal open={invOpen} onClose={() => setInvOpen(false)} target={invTarget}
      onSave={(id, segKey, inv) => updateCase(id, { invoices: { ...(cases.find((x) => x.id === id) || {}).invoices, [segKey]: inv } })} toast={toast} />
      <window.AISettingsModal open={settingsOpen} onClose={()=>setSettingsOpen(false)} />
      <window.Toast msg={toastMsg} />
    </div>);

}

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