// Phases where a create-session's plan exists but hasn't cleared the
// plan-approval gate yet. A project stuck here is a "planned" draft with no
// path back to its chat/approve loop from the card alone (the card is keyed
// on the project slug; the session is keyed on its own id) — see
// sessionByDraftSlug below.
const REENTRY_PHASES = new Set(['planning', 'reviewing', 'plan_gate']);

// Repo grouping shared with the header switcher (lib/project-groups.js).
const groupsOf = (projects) => window.ProjectGroups.groupProjectsByRepo(projects);

// Cross-project landing: composes window.ProjectCard. Progress/review counts
// arrive in slice 2 (live board data); slice 1 shows identity + boards + Open.
function ProjectsOverview({ projects }) {
  const [starting, setStarting] = React.useState(false);
  const [startError, setStartError] = React.useState(null);
  const [createSessions, setCreateSessions] = React.useState([]);
  // Fetched once, alongside (not blocking) the projects list — only used to
  // build the re-entry map below, so a fetch failure just means no "Review
  // plan" action shows up rather than breaking the overview.
  React.useEffect(() => {
    window.Api.listCreateSessions()
      .then((res) => setCreateSessions(Array.isArray(res?.sessions) ? res.sessions : []))
      .catch(() => {});
  }, []);
  // draftSlug -> session, restricted to REENTRY_PHASES. Once a session reaches
  // line_setup the ordinary "Set up line" action already covers re-entry, so
  // it's deliberately excluded here.
  const sessionByDraftSlug = {};
  for (const s of createSessions) {
    if (s.draftSlug && REENTRY_PHASES.has(s.phase)) sessionByDraftSlug[s.draftSlug] = s;
  }
  // "+ New project" starts a create session directly — the /projects/new picker
  // stays reachable by URL for resuming sessions. A creation failure surfaces
  // here: redirecting to the picker would just hide the error behind a second
  // "Start new" click against the same dead service.
  const startNew = () => {
    if (starting) return;
    setStarting(true);
    setStartError(null);
    window.Api.createSession()
      .then((s) => window.navigate('/projects/new/' + s.id))
      .catch((e) => {
        setStartError((e && e.message) || 'Could not start a new project');
        setStarting(false);
      });
  };
  return (
    <div className="max-w-5xl mx-auto p-8">
      <h1 className="text-2xl font-bold text-neutral-800 mb-1">Projects</h1>
      <p className="text-neutral-500 mb-6">Pick a project to open its live board.</p>
      {startError && (
        <div className="mb-4 rounded-lg bg-red-50 border border-red-200 p-3 text-sm text-red-800 flex items-start justify-between gap-3">
          <span>Could not start a new project — {startError}</span>
          <button onClick={() => setStartError(null)} className="text-red-500 hover:text-red-700 shrink-0 font-semibold">✕</button>
        </div>
      )}
      {/* One section per GitHub repo, its lines' cards beneath — the same grouping
          the header switcher uses (lib/project-groups.js), so the two surfaces
          cannot drift. "+ New project" sits after every section: it belongs to no
          repo, and a project only joins one once it launches. */}
      {groupsOf(projects).map((g) => (
        <section key={g.label} className="mb-6">
          <div className="mb-2 px-1 text-[10px] font-bold uppercase tracking-widest text-neutral-400 truncate" title={g.label}>
            {g.label}
          </div>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
            {g.items.map((p) => {
              const reentrySession = p.status === 'draft' && p.draftStatus === 'planned' ? sessionByDraftSlug[p.slug] : undefined;
              return (
                <window.ProjectCard
                  key={p.slug}
                  project={p}
                  onOpen={(slug) => window.navigate(`/projects/${slug}`)}
                  onAction={(pp) => window.navigate(
                    ('launching' === pp.draftStatus || 'live' === pp.draftStatus || 'launch_failed' === pp.draftStatus)
                      ? `/projects/${pp.slug}/launch`
                      : `/projects/${pp.slug}/line`
                  )}
                  reentryAction={reentrySession ? {
                    label: 'Review plan',
                    onClick: () => window.navigate('/projects/new/' + reentrySession.id),
                  } : undefined}
                />
              );
            })}
          </div>
        </section>
      ))}
      <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
        <button
          onClick={startNew}
          disabled={starting}
          className="border border-dashed border-neutral-300 rounded-2xl p-5 flex items-center justify-center font-semibold text-neutral-400 hover:border-indigo-300 hover:text-indigo-600 hover:bg-indigo-50/40 transition-all disabled:opacity-60"
        >
          {starting ? 'Starting…' : '+ New project'}
        </button>
      </div>
      {projects.length === 0 && (
        <div className="text-neutral-400 mt-6">No projects configured. Add one to <code>assembly-line-frontend/projects.json</code>.</div>
      )}
    </div>
  );
}

window.ProjectsOverview = ProjectsOverview;
