// PlanningView — the post-launch, READ-ONLY planning surface for a LIVE project
// (slice R9c, decision 14b) at /projects/:slug/planning. Page tier: it fetches the
// sealed planning artifacts ONCE (the launch seal freezes them — no polling, no
// chat editing, no gates) and renders the same three artifacts the create canvas
// showed — brief, plan gantt, station line — now frozen at the approved seal.
//
// Data: GET /projects/:slug/planning.json → { brief: string|null, plan: object|null,
//   lineGraph: object|null }. Every piece is independent and optional: a pre-R9
//   launch has no brief.md, a pre-R2 launch no plan.json/line-graph.json — each
//   section shows an honest "available after the next launch" empty state.
//
// Sections render in normal document flow (NOT the pan/zoom create canvas), so we
// use the document-flow components rather than the canvas-world Section variants
// (BriefSection/TimelineSection/StationGraphSection need an AssemblyCanvas host +
// an `origin` and are unusable off-canvas):
//   • Brief    — window.MarkdownView (BriefSection's own render core)
//   • Timeline — window.Timeline fed by window.PlanToGantt.planToGantt(plan)
//   • Line     — window.LineCanvas graph={lineGraph.graph} readOnly (self-contained
//                read-only station canvas: its own pan/zoom/fit, no editing)
//
// Rules: page tier — the ONLY fetch lives here (composition rule #1). Pure read.

const { useState: useStatePV, useEffect: useEffectPV } = React;

const PLANNING_EMPTY = 'Available after the next launch.';

function PlanningSection({ title, meta, children }) {
  return (
    <section className="mb-8">
      <div className="mb-2 px-1 flex items-baseline justify-between gap-3">
        <span className="text-[10px] uppercase font-bold tracking-widest text-neutral-500 select-none">{title}</span>
        {meta && <span className="text-xs text-neutral-500">{meta}</span>}
      </div>
      {children}
    </section>
  );
}

function PlanningEmpty() {
  return (
    <div className="rounded-2xl border border-dashed border-neutral-200 bg-neutral-50/60 px-4 py-6 text-sm text-neutral-400">
      {PLANNING_EMPTY}
    </div>
  );
}

function PlanningView({ slug }) {
  const [state, setState] = useStatePV({ loading: true, error: null, data: null });

  // Fetch once per slug — the seal is immutable, so there is nothing to poll.
  useEffectPV(() => {
    let alive = true;
    setState({ loading: true, error: null, data: null });
    fetch(`/projects/${encodeURIComponent(slug)}/planning.json`, { credentials: 'same-origin' })
      .then((res) => { if (!res.ok) throw new Error(`planning.json: ${res.status}`); return res.json(); })
      .then((data) => { if (alive) setState({ loading: false, error: null, data }); })
      .catch((err) => { if (alive) setState({ loading: false, error: String(err?.message ?? err), data: null }); });
    return () => { alive = false; };
  }, [slug]);

  if (state.loading) {
    return <div className="max-w-5xl mx-auto p-16 text-center text-neutral-400">Loading planning…</div>;
  }
  if (state.error) {
    return (
      <div className="max-w-3xl mx-auto p-16 text-center">
        <div className="text-lg font-semibold text-neutral-600 mb-1">Planning unavailable</div>
        <div className="text-neutral-400">{state.error}</div>
      </div>
    );
  }

  const { brief, plan, lineGraph } = state.data || {};
  const gantt = plan && window.PlanToGantt ? window.PlanToGantt.planToGantt(plan) : null;
  const graph = lineGraph && lineGraph.graph ? lineGraph.graph : null;

  return (
    <div className="max-w-5xl mx-auto px-6 py-8">
      <div className="mb-6">
        <div className="text-xs font-bold uppercase tracking-widest text-indigo-600">Planning · sealed at launch</div>
        <div className="text-sm text-neutral-500 mt-1">A read-only snapshot of the brief, plan and line this project launched with.</div>
      </div>

      <PlanningSection title="Brief · what we're building">
        {brief ? (
          <div className="rounded-2xl border border-neutral-200 bg-white shadow-sm px-4 py-3">
            <window.MarkdownView markdown={brief} />
          </div>
        ) : <PlanningEmpty />}
      </PlanningSection>

      {/* The scheduled/unscheduled count was the ONE thing the standalone
          "Plan & timeline" page showed that this view did not. Carrying it here
          makes hiding that tab on a launched project lossless. */}
      <PlanningSection
        title="Timeline · the plan"
        meta={gantt ? `${gantt.rows.length} scheduled · ${gantt.unscheduled.length} unscheduled` : null}
      >
        {gantt ? (
          <div className="rounded-2xl border border-neutral-200 bg-white shadow-sm px-4 py-3">
            <window.Timeline gantt={gantt} />
          </div>
        ) : <PlanningEmpty />}
      </PlanningSection>

      <PlanningSection title="Stations · the line that builds it">
        {graph ? (
          <div className="rounded-2xl border border-neutral-200 bg-white shadow-sm overflow-hidden relative" style={{ height: 460 }}>
            <window.LineCanvas graph={graph} readOnly />
          </div>
        ) : <PlanningEmpty />}
      </PlanningSection>
    </div>
  );
}

if (typeof window !== 'undefined') {
  window.PlanningView = PlanningView;
}
