// Root app shell

const NAV = [
  { group: 'WORKSPACE', items: [
    { id: 'dashboard', label: 'Dashboard',  icon: 'home' },
    { id: 'jobs',      label: 'Lowongan',   icon: 'briefcase' },
    { id: 'candidates', label: 'Kandidat',  icon: 'layout' },
    { id: 'calendar',  label: 'Kalender',   icon: 'clock' },
    { id: 'team',      label: 'Tim HR',     icon: 'users' },
    { id: 'import',    label: 'Import Kandidat', icon: 'download' },
    { id: 'search',    label: 'Pencarian AI', icon: 'sparkles' },
    { id: 'papi',      label: 'Psikotes', icon: 'file' },
  ]},
  { group: 'INTEGRASI', items: [
    { id: 'whatsapp',  label: 'WhatsApp Bot', icon: 'message' },
    { id: 'public',    label: 'Halaman Publik', icon: 'globe' },
  ]},
  { group: 'AKUN', items: [
    { id: 'settings',  label: 'Pengaturan', icon: 'settings' },
  ]},
];

const TWEAK_DEFAULS = /*EDITMODE-BEGIN*/{
  "accent": "#3a6df0",
  "density": "comfort",
  "showAiSummary": true
}/*EDITMODE-END*/;

// Company (organization) switcher — one account can own several companies.
// Switching reloads the page so all data re-fetches under the new company.
function CompanySwitcher() {
  const { ORGS = [], ACTIVE_ORG_ID } = window.TalentirData;
  const [open, setOpen] = useState(false);
  const [busy, setBusy] = useState(false);
  const active = ORGS.find(o => o.id === ACTIVE_ORG_ID) || ORGS[0];

  const switchTo = async (orgId) => {
    setOpen(false);
    if (orgId === ACTIVE_ORG_ID) return;
    setBusy(true);
    try { await window.TalentirAPI.post('/api/orgs/switch', { orgId }); window.location.reload(); }
    catch (e) { console.error('Gagal ganti perusahaan:', e); setBusy(false); }
  };
  const addCompany = async () => {
    setOpen(false);
    const name = window.prompt('Nama perusahaan baru:');
    if (!name || !name.trim()) return;
    setBusy(true);
    try {
      const org = await window.TalentirAPI.post('/api/orgs', { name: name.trim() });
      await window.TalentirAPI.post('/api/orgs/switch', { orgId: org.id });
      window.location.reload();
    } catch (e) { console.error('Gagal membuat perusahaan:', e); setBusy(false); }
  };

  return (
    <div className="nav-section" style={{ position: 'relative' }}>
      <div className="label">PERUSAHAAN</div>
      <div className="nav-item" onClick={() => !busy && setOpen(o => !o)} style={{ cursor: 'pointer' }}>
        <Icon name="briefcase" size={15} className="ico"/>
        <span style={{ flex: 1, fontWeight: 700, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{busy ? 'Memuat…' : (active?.name || 'Perusahaan')}</span>
        <Icon name="chevronD" size={14}/>
      </div>
      {open && (
        <div style={{ position: 'absolute', left: 8, right: 8, top: '100%', zIndex: 30, background: 'var(--surface)', border: '1px solid var(--border)', borderRadius: 10, boxShadow: '0 12px 30px rgba(15,23,42,.18)', padding: 6, marginTop: 2 }}>
          {ORGS.map(o => (
            <div key={o.id} onClick={() => switchTo(o.id)} className="row-flex"
                 style={{ padding: '8px 10px', borderRadius: 7, cursor: 'pointer', fontSize: 13, gap: 8, background: o.id === ACTIVE_ORG_ID ? 'var(--bg-soft)' : 'transparent' }}>
              <span style={{ width: 14, display: 'inline-flex' }}>{o.id === ACTIVE_ORG_ID && <Icon name="check" size={12} stroke={2.6} style={{ color: 'var(--accent)' }}/>}</span>
              <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', fontWeight: o.id === ACTIVE_ORG_ID ? 700 : 500 }}>{o.name}</span>
            </div>
          ))}
          <div className="divider" style={{ margin: '5px 0' }}/>
          <div onClick={addCompany} className="row-flex" style={{ padding: '8px 10px', borderRadius: 7, cursor: 'pointer', fontSize: 13, gap: 8, color: 'var(--accent)', fontWeight: 700 }}>
            <Icon name="plus" size={13}/> Tambah Perusahaan
          </div>
        </div>
      )}
    </div>
  );
}

function App() {
  const { JOBS, CANDIDATES } = window.TalentirData;
  const [route, setRoute] = useState({ view: 'dashboard' });
  const [drawerCand, setDrawerCand] = useState(null);
  const [candidates, setCandidates] = useState(CANDIDATES);
  const [interviews, setInterviews] = useState(window.TalentirData.INTERVIEWS);
  const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULS);
  // Bumped after jobs/WA mutations to re-render views that read these straight
  // from window.TalentirData (which loadTalentirData refreshes from the API).
  const [, setDataVersion] = useState(0);
  const reloadData = async () => {
    try { await window.loadTalentirData(); setDataVersion(v => v + 1); }
    catch (err) { console.error('Gagal memuat ulang data:', err); }
  };

  // Apply accent tweak as CSS var
  useEffect(() => {
    if (tweaks.accent) {
      document.documentElement.style.setProperty('--accent', tweaks.accent);
      // soft tinted bg
      document.documentElement.style.setProperty('--accent-2', tweaks.accent + '20');
    }
  }, [tweaks.accent]);

  const openCandidate = (c) => setDrawerCand(c);
  // Prepend a newly-created candidate (manual add) to the pipeline.
  const addCandidate = (c) => setCandidates(prev => [c, ...prev]);
  // Optimistic local update + persist to the backend. Covers Kanban drag,
  // the drawer's status/assignee pickers, and bulk distribute (all funnel here).
  const updateCandidate = (c) => {
    setCandidates(prev => prev.map(x => x.id === c.id ? c : x));
    window.TalentirAPI
      .patch('/api/candidates/' + c.id, { status: c.status, assignedTo: c.assignedTo, score: c.score })
      .catch(err => console.error('Gagal menyimpan kandidat:', err));
  };
  const onUpdateDrawer = (c) => { updateCandidate(c); setDrawerCand(c); };

  const importCandidates = (imported, jobId, autoTrigger = false) => {
    const payload = imported.map(p => ({
      name: p.name,
      email: p.email,
      phone: p.phone,
      location: p.location,
      age: 25 + (p.name.length % 12),
      experience: p.experience,
      score: p.score,
      source: p.source,
      tags: (p.skills || []).slice(0, 2),
      hasWa: true,
      hasCv: !!p.cvUrl,
      cvUrl: p.cvUrl || null,
      cvFileId: p.cvFileId || null,
    }));
    // Optimistic insert so the success screen + pipeline show them immediately…
    const optimistic = payload.map((p, i) => ({
      ...p, id: 'imp-' + Date.now() + '-' + i, jobId, status: 'ai',
      appliedAt: new Date().toISOString().slice(0, 10),
      hasWA: true, hasCV: true, assignedTo: null,
    }));
    setCandidates(prev => [...optimistic, ...prev]);
    // …then persist and reconcile with the rows the backend actually stored.
    window.TalentirAPI
      .post('/api/import', { source: imported[0]?.source || 'jobportal', jobId, autoTrigger, candidates: payload })
      .then(res => {
        const saved = (res.candidates || []).map(window.TalentirAPI.mapCandidate);
        const optimisticIds = new Set(optimistic.map(o => o.id));
        setCandidates(prev => [...saved, ...prev.filter(c => !optimisticIds.has(c.id))]);
      })
      .catch(err => console.error('Gagal import kandidat:', err));
  };

  const go = (r) => { setRoute(r); setDrawerCand(null); };

  const addInterview = (iv) => {
    setInterviews(prev => [...prev, iv]); // optimistic
    window.TalentirAPI
      .post('/api/interviews', {
        candidateId: iv.candidateId, hrId: iv.hrId, jobId: iv.jobId,
        date: iv.date, start: iv.start, durationMin: iv.durationMin,
        mode: iv.mode, meetingUrl: iv.meetingUrl, status: iv.status, notes: iv.notes,
      })
      .then(saved => setInterviews(prev => prev.map(x => x.id === iv.id ? saved : x)))
      .catch(err => console.error('Gagal menyimpan jadwal:', err));
  };

  const updateInterview = (iv) => {
    setInterviews(prev => prev.map(x => x.id === iv.id ? iv : x));
    window.TalentirAPI
      .patch('/api/interviews/' + iv.id, {
        date: iv.date, start: iv.start, durationMin: iv.durationMin,
        mode: iv.mode, meetingUrl: iv.meetingUrl, status: iv.status, notes: iv.notes, hrId: iv.hrId,
      })
      .catch(err => console.error('Gagal memperbarui jadwal:', err));
  };

  const cancelInterview = (id) => {
    setInterviews(prev => prev.filter(x => x.id !== id));
    fetch(window.TalentirAPI.base + '/api/interviews/' + id, {
      method: 'DELETE', credentials: 'include',
    }).catch(err => console.error('Gagal membatalkan jadwal:', err));
  };

  const job = route.jobId ? JOBS.find(j => j.id === route.jobId) : null;

  return (
    <div className="app">
      {/* Sidebar */}
      <aside className="sidebar">
        <div className="brand">
          <div className="mark">T</div>
          <div className="wm">Talent<em>ir</em></div>
        </div>

        <CompanySwitcher/>

        {NAV.map(g => (
          <div key={g.group} className="nav-section">
            <div className="label">{g.group}</div>
            {g.items.map(it => (
              <div key={it.id}
                   className={'nav-item ' + (route.view === it.id ? 'active' : '')}
                   onClick={() => go({ view: it.id })}>
                <Icon name={it.icon} size={15} className="ico"/>
                <span>{it.label}</span>
                {it.pill && <span className="pill">{it.pill}</span>}
              </div>
            ))}
          </div>
        ))}

        <div className="nav-section" style={{ marginTop: 'auto' }}>
          <div className="label">QUICK ACTIONS</div>
          <button className="btn primary" style={{ width: '100%', justifyContent: 'center' }}
                  onClick={() => go({ view: 'jobs', subview: 'new' })}>
            <Icon name="plus" size={14}/> Posisi Baru
          </button>
          <button className="btn" style={{ width: '100%', justifyContent: 'center', marginTop: 6 }}
                  onClick={() => go({ view: 'import' })}>
            <Icon name="download" size={14}/> Import Kandidat
          </button>
        </div>

        <div className="side-foot" onClick={() => go({ view: 'settings' })} style={{ cursor: 'pointer' }} title="Buka Pengaturan">
          <Avatar name={(window.TalentirData.USER && window.TalentirData.USER.name) || 'Reza Alfian'}/>
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{ fontWeight: 700, fontSize: 13, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{(window.TalentirData.USER && window.TalentirData.USER.name) || 'Reza Alfian'}</div>
            <div style={{ fontSize: 11, color: 'var(--muted)' }}>{window.TalentirData.ORG_NAME || 'Perusahaan'}</div>
          </div>
          <span className="btn icon ghost" title="Pengaturan"><Icon name="settings" size={14}/></span>
        </div>
      </aside>

      {/* Main */}
      <main className="main">
        {/* Topbar */}
        <div className="topbar">
          <div className="crumbs">
            <span>Talentir</span>
            <Icon name="chevron" size={12} className="sep"/>
            <span className={!route.jobId ? 'now' : ''}>
              {route.view === 'dashboard' && 'Dashboard'}
              {route.view === 'jobs' && (route.subview === 'new' ? 'Posisi Baru' : 'Lowongan')}
              {route.view === 'candidates' && 'Database Kandidat'}
              {route.view === 'calendar' && 'Kalender Wawancara'}
              {route.view === 'team' && 'Tim HR'}
              {route.view === 'import' && 'Import Kandidat'}
              {route.view === 'search' && 'Pencarian AI'}
              {route.view === 'papi' && 'Psikotes — PAPI Kostick'}
              {route.view === 'whatsapp' && 'WhatsApp Bot'}
              {route.view === 'public' && 'Halaman Publik'}
              {route.view === 'settings' && 'Pengaturan'}
            </span>
            {job && <>
              <Icon name="chevron" size={12} className="sep"/>
              <span className="now">{job.title}</span>
            </>}
          </div>
          <div className="spacer"/>
          <div className="quick-search" onClick={() => go({ view: 'search' })}>
            <Icon name="search" size={14}/>
            <span>Tanya AI atau cari kandidat…</span>
            <kbd>⌘K</kbd>
          </div>
          {/* Notification bell removed — no notification system yet, so an
              icon that does nothing only confuses users. Add back when there's
              a real feed (badge count + dropdown of recent activity). */}
        </div>

        {route.view === 'dashboard' && <DashboardView go={go} openCandidate={openCandidate}/>}
        {route.view === 'jobs' && <JobsView state={route} go={go} openCandidate={openCandidate} candidates={candidates} updateCandidate={updateCandidate} addCandidate={addCandidate} reloadData={reloadData}/>}
        {route.view === 'candidates' && <CandidatesView candidates={candidates} openCandidate={openCandidate} go={go}/>}
        {route.view === 'calendar' && <CalendarView openCandidate={openCandidate} candidates={candidates} interviews={interviews} addInterview={addInterview} updateInterview={updateInterview} cancelInterview={cancelInterview} go={go} scheduleFor={route.scheduleFor}/>}
        {route.view === 'team' && <TeamView candidates={candidates} openCandidate={openCandidate} go={go} reloadData={reloadData}/>}
        {route.view === 'import' && <ImportView state={route} go={go} onImport={importCandidates}/>}
        {route.view === 'search' && <SearchView openCandidate={openCandidate}/>}
        {route.view === 'papi' && <PapiView go={go} state={route}/>}
        {route.view === 'whatsapp' && <WhatsAppView candidates={candidates} openCandidate={openCandidate} reloadData={reloadData}/>}
        {route.view === 'public' && <PublicView state={route} go={go}/>}
        {route.view === 'settings' && <SettingsView go={go}/>}
      </main>

      {/* Drawer */}
      {drawerCand && (
        <CandidateDrawer
          candidate={drawerCand}
          job={JOBS.find(j => j.id === drawerCand.jobId)}
          onClose={() => setDrawerCand(null)}
          onUpdate={onUpdateDrawer}
          onSchedule={(c) => { setDrawerCand(null); go({ view: 'calendar', scheduleFor: c.id }); }}
          onPapi={(c) => { setDrawerCand(null); go({ view: 'papi', candidateId: c.id }); }}/>
      )}

      {/* Tweaks Panel */}
      <window.TweaksPanel title="Tweaks">
        <window.TweakSection label="Tampilan">
          <window.TweakColor label="Warna aksen"
            value={tweaks.accent}
            onChange={(v) => setTweak('accent', v)}
            options={['#3a6df0', '#1f7a4d', '#8b5cf6', '#e0612b', '#0f172a']}/>
          <window.TweakRadio label="Density"
            value={tweaks.density}
            onChange={(v) => setTweak('density', v)}
            options={[
              { label: 'Comfort', value: 'comfort' },
              { label: 'Compact', value: 'compact' },
            ]}/>
          <window.TweakToggle label="Ringkasan AI"
            value={tweaks.showAiSummary}
            onChange={(v) => setTweak('showAiSummary', v)}/>
        </window.TweakSection>
      </window.TweaksPanel>
    </div>
  );
}

// Rendered by boot.jsx once the session is verified and data is loaded.
window.App = App;
