// WeWire team dashboard — root.

const TEAM_VIEWS = new Set(['overview', 'pipeline', 'compare', 'prompts', 'interviews', 'team']);

function teamBasePath() {
  return (window.WWPaths?.team?.() || '/team/').replace(/\/+$/, '');
}

function viewFromPathname() {
  const parts = window.location.pathname.replace(/\/$/, '').split('/').filter(Boolean);
  const teamIdx = parts.lastIndexOf('team');
  const sub = teamIdx >= 0 ? parts[teamIdx + 1] : parts[parts.length - 1];
  if (sub && TEAM_VIEWS.has(sub)) return sub;
  return 'overview';
}

function App() {
  const [booting, setBooting] = React.useState(true);
  const [authed, setAuthed] = React.useState(false);
  const [adminEmail, setAdminEmail] = React.useState('');
  const [authError, setAuthError] = React.useState('');
  const [data, setData] = React.useState([]);
  const [loadError, setLoadError] = React.useState('');
  const [view, setViewState] = React.useState(viewFromPathname);
  const [selected, setSelected] = React.useState([]);
  const [profileId, setProfileId] = React.useState(null);

  const useLive = window.WWSupabase && window.WWSupabase.enabled();

  const setView = React.useCallback((next) => {
    setViewState(next);
    const base = teamBasePath();
    const path = next === 'overview' ? `${base}/` : `${base}/${next}`;
    const current = window.location.pathname.replace(/\/$/, '') || '/';
    const target = path.replace(/\/$/, '') || '/';
    if (current !== target) {
      window.history.pushState({ view: next }, '', path);
    }
  }, []);

  React.useEffect(() => {
    const onPop = () => setViewState(viewFromPathname());
    window.addEventListener('popstate', onPop);
    return () => window.removeEventListener('popstate', onPop);
  }, []);

  React.useEffect(() => {
    if (!authed || !useLive) return;
    if (view === 'interviews' || view === 'overview') {
      WWAdmin.fetchApplicants().then(setData).catch(() => {});
    }
  }, [view, authed, useLive]);

  const authErrorMessage = (reason, errMsg) => {
    if (reason === 'not_allowlisted') {
      return 'This email is not on the recruiting allowlist. Ask an admin to add your email to admin_users in Supabase.';
    }
    if (reason === 'no_session') {
      return 'Please sign in to continue.';
    }
    return errMsg || 'Could not sign in.';
  };

  const enterDashboard = async (access) => {
    setAuthed(true);
    setAdminEmail(access.session.user.email);
    setAuthError('');
    const rows = await WWAdmin.fetchApplicants();
    setData(rows);
  };

  React.useEffect(() => {
    (async () => {
      if (!useLive) {
        if (window.WW_DEV) {
          const seed = window.WWData.APPLICANTS.map(a => ({ ...a, rating: 0, notes: '' }));
          setData(seed);
          setAuthed(true);
        } else {
          setAuthError('Team login requires Supabase. Add SUPABASE_URL, SUPABASE_ANON_KEY, and SUPABASE_SERVICE_ROLE_KEY in your Render service environment variables, then redeploy.');
        }
        setBooting(false);
        return;
      }

      try {
        const access = await WWAdmin.checkAdminAccess();
        if (!access.ok) {
          if (access.reason !== 'no_session') {
            setAuthError(authErrorMessage(access.reason));
          }
          if (window.WWSupabase?.bootstrapFromServer) {
            await window.WWSupabase.bootstrapFromServer();
          }
          setBooting(false);
          return;
        }
        await enterDashboard(access);
      } catch (err) {
        setAuthError(authErrorMessage(null, err.message));
      } finally {
        setBooting(false);
      }
    })();
  }, [useLive]);

  const refresh = async () => {
    if (!useLive) return;
    const rows = await WWAdmin.fetchApplicants();
    setData(rows);
  };

  const openProfile = (id) => setProfileId(id);
  const toggleSelect = (id) => setSelected(s => s.includes(id) ? s.filter(x => x !== id) : [...s, id]);

  const onDelete = async (id) => {
    if (!confirm('Permanently remove this candidate and all their data? This cannot be undone.')) return;
    if (useLive) {
      try {
        await WWAdmin.deleteApplicant(id);
      } catch (err) {
        alert(err.message || 'Could not remove candidate. They are still in the pipeline.');
        return;
      }
    }
    setData((d) => d.filter((a) => a.id !== id));
    setProfileId(null);
    setSelected((s) => s.filter((x) => x !== id));
  };

  const onBulkDelete = async () => {
    if (selected.length === 0) return;
    if (!confirm(`Permanently remove ${selected.length} candidate(s) and all their data? This cannot be undone.`)) return;
    const ids = [...selected];
    if (useLive) {
      const failed = [];
      for (const id of ids) {
        try {
          await WWAdmin.deleteApplicant(id);
        } catch (err) {
          failed.push(id);
          console.warn(id, err.message);
        }
      }
      if (failed.length) {
        alert(
          failed.length === ids.length
            ? 'Could not remove the selected candidates. Nothing was deleted.'
            : `Removed ${ids.length - failed.length} of ${ids.length}. ${failed.length} could not be deleted — refresh and try again.`,
        );
      }
      const removed = new Set(ids.filter((id) => !failed.includes(id)));
      setData((d) => d.filter((a) => !removed.has(a.id)));
      setSelected((s) => s.filter((id) => !removed.has(id)));
      if (profileId && removed.has(profileId)) setProfileId(null);
      return;
    }
    setData((d) => d.filter((a) => !ids.includes(a.id)));
    setSelected([]);
    setProfileId(null);
  };

  const onStatus = async (id, status) => {
    setData(d => d.map(a => a.id === id ? { ...a, status } : a));
    if (useLive) {
      try { await WWAdmin.updateApplicant(id, { status }); } catch (err) { console.warn(err.message); }
    }
  };

  const onUpdate = async (id, patch) => {
    setData(d => d.map(a => a.id === id ? { ...a, ...patch } : a));
    if (useLive) {
      try { await WWAdmin.updateApplicant(id, patch); } catch (err) { console.warn(err.message); }
    }
  };

  const onStageReview = async (id, stageKey, patch) => {
    const cand = data.find(a => a.id === id);
    if (!cand) return;
    const { essayId, ...reviewPatch } = patch;
    const meta = {
      review: reviewPatch.review,
      reviewedBy: reviewPatch.reviewedBy,
      reviewedAt: reviewPatch.reviewedAt,
    };

    setData(d => d.map(a => {
      if (a.id !== id) return a;
      if (stageKey === 'written' && essayId) {
        const essays = [...(window.WWFunnel?.writtenEssaysFromPayload(a.stagePayload?.written) || [])];
        const idx = essays.findIndex((e) => e.id === essayId);
        if (idx >= 0) {
          essays[idx] = { ...essays[idx], ...meta, score: reviewPatch.score };
        }
        const avg = window.WWFunnel?.averageEssayScore(essays) ?? reviewPatch.score;
        return {
          ...a,
          scores: { ...a.scores, written: avg },
          stagePayload: {
            ...a.stagePayload,
            written: { ...(a.stagePayload?.written || {}), essays },
          },
        };
      }
      return {
        ...a,
        scores: { ...a.scores, [stageKey]: reviewPatch.score },
        stagePayload: {
          ...a.stagePayload,
          [stageKey]: { ...(a.stagePayload?.[stageKey] || {}), ...meta, score: reviewPatch.score },
        },
      };
    }));

    if (useLive && cand.dbId) {
      const saved = await WWAdmin.saveStageReview(cand.dbId, stageKey, patch);
      setData(d => d.map(a => {
        if (a.id !== id) return a;
        if (stageKey === 'written' && essayId) {
          const essays = [...(window.WWFunnel?.writtenEssaysFromPayload(a.stagePayload?.written) || [])];
          const idx = essays.findIndex((e) => e.id === essayId);
          if (idx >= 0) {
            essays[idx] = { ...essays[idx], review: saved.review, reviewedBy: saved.reviewedBy, reviewedAt: saved.reviewedAt, score: saved.essayScore ?? reviewPatch.score };
          }
          return {
            ...a,
            scores: { ...a.scores, written: saved.score },
            stagePayload: { ...a.stagePayload, written: { ...(a.stagePayload?.written || {}), essays } },
          };
        }
        return {
          ...a,
          scores: { ...a.scores, [stageKey]: saved.score },
          stagePayload: {
            ...a.stagePayload,
            [stageKey]: { ...(a.stagePayload?.[stageKey] || {}), ...saved },
          },
        };
      }));
    }
  };

  const signOut = async () => {
    if (useLive) await WWAdmin.signOut();
    location.reload();
  };

  const exportCsv = async () => {
    if (!useLive) {
      alert('CSV export requires Supabase. Configure SUPABASE_URL in .env and restart the server.');
      return;
    }
    const token = await WWAdmin.getAccessToken();
    const url = WWAdmin.exportCsvUrl();
    const res = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
    if (!res.ok) { alert('Export failed.'); return; }
    const blob = await res.blob();
    const a = document.createElement('a');
    a.href = URL.createObjectURL(blob);
    a.download = 'wewire-applicants.csv';
    a.click();
  };

  if (booting) {
    return (
      <div style={{ height: '100vh', display: 'grid', placeItems: 'center', background: T.cream }}>
        <div style={{ fontSize: 15, color: T.muted }}>Loading dashboard…</div>
      </div>
    );
  }

  if (!authed) {
    return <AdminLogin error={authError} onAuthenticated={enterDashboard} />;
  }

  const cand = data.find(a => a.id === profileId);

  return (
    <div style={{ display: 'flex', height: '100vh', overflow: 'hidden', background: T.cream }}
      data-screen-label={'Dashboard · ' + view}>
      <Sidebar view={view} setView={setView} adminEmail={adminEmail} onSignOut={useLive ? signOut : null} onExport={exportCsv} />
      <main style={{ flex: 1, overflowY: 'auto', background: T.cream }}>
        {loadError && (
          <div style={{ padding: 16, background: T.redSoft, color: T.red, fontSize: 14 }}>{loadError}</div>
        )}
        {view === 'overview' && <Overview data={data} setView={setView} openProfile={openProfile} />}
        {view === 'pipeline' && <Pipeline data={data} openProfile={openProfile} selected={selected} toggleSelect={toggleSelect} setView={setView} onBulkDelete={onBulkDelete} />}
        {view === 'compare' && <Compare data={data} selected={selected} toggleSelect={toggleSelect} setSelected={setSelected} setView={setView} openProfile={openProfile} />}
        {view === 'prompts' && <StagePrompts useLive={useLive} />}
        {view === 'interviews' && <InterviewSlots useLive={useLive} data={data} />}
        {view === 'team' && <TeamManagement useLive={useLive} adminEmail={adminEmail} />}
      </main>
      {cand && <Profile cand={cand} onClose={() => setProfileId(null)} onStatus={onStatus} onDelete={onDelete} onUpdate={onUpdate}
        onStageReview={onStageReview} useLive={useLive} />}
    </div>
  );
}

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