/* =========================================================
   main.jsx — App shell, screen routing, REPLAY mode
   ========================================================= */

const SCREENS = {
  today:    (onGo, project, setProject) => <ScreenTodayV2 onGo={onGo} project={project} setProject={setProject} />,
  financeToday: (onGo, project, setProject) => <ScreenTodayV2 onGo={onGo} project={project} setProject={setProject} />,
  schedulingToday: (onGo, project, setProject) => <ScreenTodayV2 onGo={onGo} project={project} setProject={setProject} />,
  estimate: (onGo, project, setProject) => <ScreenEstimatorV2 onGo={onGo} project={project} setProject={setProject} />,
  quotes:   (onGo, project, setProject) => <ScreenTradeCoordinatorV2 onGo={onGo} project={project} setProject={setProject} />,
  bills:    (onGo, project, setProject) => <ScreenBookkeeperV2 onGo={onGo} project={project} setProject={setProject} />,
  field:    (onGo, project, setProject) => <ScreenFieldIntakeV2 onGo={onGo} project={project} setProject={setProject} />,
  mailroom: (onGo, project, setProject) => <ScreenJobsV2 onGo={onGo} project={project} setProject={setProject} />,
  channels: (onGo, project, setProject) => <ScreenJobsV2 onGo={onGo} project={project} setProject={setProject} />,
  schedule: (onGo, project, setProject) => <ScreenSchedulerV2 onGo={onGo} project={project} setProject={setProject} />,
  project:  (onGo, project, setProject) => <ScreenJobsV2 onGo={onGo} project={project} setProject={setProject} />,
  client:   (onGo, project, setProject) => <ScreenClientLiaisonV2 onGo={onGo} project={project} setProject={setProject} />,
  staff:    (onGo, project, setProject) => <ScreenTodayV2 onGo={onGo} project={project} setProject={setProject} />,
  receipts: (onGo, project, setProject) => <ScreenJobsV2 onGo={onGo} project={project} setProject={setProject} />,
  ask:      (onGo, project, setProject) => <ScreenTodayV2 onGo={onGo} project={project} setProject={setProject} />,
  timekeeper: (onGo, project, setProject) => <ScreenTimekeeperV2 onGo={onGo} project={project} setProject={setProject} />,
  accounting: (onGo, project, setProject) => <ScreenAccountingAnalystV2 onGo={onGo} project={project} setProject={setProject} />,
  takeoff: (onGo, project, setProject) => <ScreenTakeoffReaderV2 onGo={onGo} project={project} setProject={setProject} />,
  support: (onGo, project, setProject) => <ScreenTodayV2 onGo={onGo} project={project} setProject={setProject} />,
  settings: (onGo, project, setProject) => <ScreenTodayV2 onGo={onGo} project={project} setProject={setProject} />,
  tour:     (onGo, project, setProject) => <ScreenTourV2 onGo={onGo} project={project} setProject={setProject} />,
};

const STORAGE_KEY        = "coordos:current-screen";
const REPLAY_ACTIVE_KEY  = "coordos:replay-active";
const REPLAY_SCENE_KEY   = "coordos:replay-scene";

const PROJECT_FILTERS = [
  { id:"all", label:"All projects", meta:"4 active houses" },
  { id:"st-leonards", label:"St Leonards", meta:"estimate + quote chase" },
  { id:"glenrose", label:"Glenrose", meta:"field + bills" },
  { id:"oakwood", label:"Oakwood", meta:"hours follow-up" },
  { id:"humber", label:"Humber", meta:"schedule risk" },
];

/* =========================================================
   REPLAY SCENES — the Glenrose office day, end to end
   ========================================================= */
const SCENES = [
  {
    k:"drawings",   screen:"mailroom", title:"Drawings arrive",
    chapter:"Preconstruction",
    did:"BCA Studio uploaded the R4 set to Drive overnight. The File Clerk filed it under /Glenrose/Drawings/R4 inside 60 seconds and Takeoff Reader queued a diff against R3.",
    approve:"Nothing for you — the office routes new drawings automatically. Just see where it landed.",
    receipt:"R4 drawing set filed to Drive · 28 sheets preserved · diff vs R3 queued.",
    action:null,
  },
  {
    k:"takeoff",    screen:"takeoff", title:"Takeoff Reader's 7 AM plan sweep",
    chapter:"Preconstruction",
    did:"Takeoff Reader read 28 sheets, counted 47 lines, flagged 3 plan questions, and generated the first rule-priced budget.",
    approve:"Reply to the plan questions only if the Takeoff Reader cannot resolve them from the drawings or architect thread.",
    receipt:"Takeoff prepared · 47 lines counted · draft budget generated · quote plan created.",
    action:{ label:"Open", icon:"doc" },
  },
  {
    k:"quotes",     screen:"quotes",   title:"Approve supplier quote requests",
    chapter:"Preconstruction",
    did:"Trade Coordinator drafted 3 quote requests (Pella · Hartman · Boulevard), each pulling the exact budget rows that need a vendor price. Apex HVAC + Pella prelim replies already folded in.",
    approve:"Approve and send all 3 — emails go from your Gmail, replies save to History and fold into the budget.",
    receipt:"3 supplier quote requests sent · 5 attachments · 1 receipt per send.",
    action:{ label:"Approve & send all 3", icon:"send" },
  },
  {
    k:"budget",     screen:"project",  title:"Budget generated",
    chapter:"Pricing & planning",
    did:"Rule-priced lines and the supplier replies that came back overnight folded into the draft budget. Framing is currently $2,140 over due to Saturday overtime and 8% lumber price.",
    approve:"Open the draft budget. Approve it, or send a note back to Takeoff Reader before quotes are final.",
    receipt:"Draft budget $634,710 saved to Glenrose Job · feeds the draft schedule.",
    action:{ label:"Review budget", icon:"ledger" },
  },
  {
    k:"schedule",   screen:"project",  title:"Draft schedule from the budget",
    chapter:"Pricing & planning",
    did:"Scheduler used the approved budget + scope to draft a 29-week Gantt: site → foundation → framing (now) → roofing → windows → rough-ins → drywall → finishes → punch.",
    approve:"Approve the schedule, or open a date and ask Scheduler to move it.",
    receipt:"Schedule approved · vendor reminders queued · client-visible milestones unlocked.",
    action:{ label:"Approve schedule", icon:"check" },
  },
  {
    k:"field",      screen:"field",    title:"Site → daily log + hours",
    chapter:"Execution",
    did:"Marco sent a 1:24 voice note + 5 photos + 4 timesheet photos this morning. Field Intake transcribed, classified the photos, drafted the daily log + RFI, and extracted hours for 5 crew members.",
    approve:"Approve the daily log. It publishes to the Job, photos file to Drive, hours stage to Bookkeeping, and the stair question emails BCA.",
    receipt:"Daily log published · 5 photos to Drive · 5 hours entries staged · RFI #014 sent.",
    action:{ label:"Approve daily log", icon:"check" },
  },
  {
    k:"bookkeeping",screen:"bills",    title:"Bills + hours into QuickBooks",
    chapter:"Execution",
    did:"Bookkeeper found 10 bills overnight, matched 6 to vendor + project + cost code, held 4 with questions. Captured 13 time entries; Frank Park's missing-hours reply came back at 7:42 AM and folded in.",
    approve:"Approve 6 bills and 12 hours to QuickBooks. Send Carlos Diaz's bilingual follow-up. Decide Jay Patel overtime.",
    receipt:"6 bills and 12 hours written to QuickBooks · $24,318 · 87 regular hours · 4.5 overtime held.",
    action:{ label:"Approve to QuickBooks", icon:"qb" },
  },
  {
    k:"accounting", screen:"bills",    title:"You ask accounting",
    chapter:"Execution",
    did:"You asked: 'Why is Glenrose framing labor over?' Bookkeeper pulled 3 bills + 4 time entries + 2 receipts and answered with three reasons: +$640 lumber, +$1,500 Sat OT, ±$0 Mateo absences.",
    approve:"Read the answer. Flag Oakwood drywall on the dashboard if you want to watch it.",
    receipt:"Accounting question answered · sourced from QuickBooks, approved hours, and bill receipts.",
    action:{ label:"See accounting answer", icon:"ask" },
  },
  {
    k:"client",     screen:"client",   title:"Weekly client update",
    chapter:"Execution",
    did:"Client Liaison drafted Thursday's note for the Glenroses: plain language, 4 selected photos, one-paragraph budget summary. Vendor disputes and mapping questions filtered out.",
    approve:"Approve and send. It sends Thursday at 8 AM from your Gmail.",
    receipt:"Client update queued · sends Thu 8 AM · 4 photos attached · 0 internal notes leak.",
    action:{ label:"Approve & send Thursday update", icon:"send" },
  },
  {
    k:"receipts",   screen:"receipts", title:"Proof of work",
    chapter:"Trust trail",
    did:"Every action your office took today is written to the ledger — drawings filed, takeoff prepared, quotes sent, bills + hours to QuickBooks, log published, accounting question answered, update queued, and follow-ups chased.",
    approve:"Nothing. The proof is yours. Open source evidence or export CSV when you want it.",
    receipt:"End of replay · the office day is closed.",
    action:{ label:"End replay", icon:"check" },
  },
];

function App() {
  const [current, setCurrent] = React.useState(() => {
    try { localStorage.setItem(STORAGE_KEY, "today"); } catch {}
    return "today";
  });
  const [replayActive, setReplayActive] = React.useState(() => {
    try { localStorage.setItem(REPLAY_ACTIVE_KEY, "0"); } catch {}
    return false;
  });
  const [sceneIdx, setSceneIdx] = React.useState(() => {
    try { return parseInt(localStorage.getItem(REPLAY_SCENE_KEY) || "0", 10); } catch { return 0; }
  });
  const [projectFilter, setProjectFilter] = React.useState("all");
  const [askOpen, setAskOpen] = React.useState(false);

  React.useEffect(() => { try { localStorage.setItem(STORAGE_KEY, current); } catch {} }, [current]);
  React.useEffect(() => { try { localStorage.setItem(REPLAY_ACTIVE_KEY, replayActive ? "1" : "0"); } catch {} }, [replayActive]);
  React.useEffect(() => { try { localStorage.setItem(REPLAY_SCENE_KEY, String(sceneIdx)); } catch {} }, [sceneIdx]);
  React.useEffect(() => {
    const resetScroll = () => {
      window.scrollTo(0, 0);
      document.documentElement.scrollTop = 0;
      document.body.scrollTop = 0;
    };
    resetScroll();
    const frame = window.requestAnimationFrame(resetScroll);
    const later = window.setTimeout(resetScroll, 80);
    const final = window.setTimeout(resetScroll, 260);
    return () => {
      window.cancelAnimationFrame(frame);
      window.clearTimeout(later);
      window.clearTimeout(final);
    };
  }, [current]);

  // when replay is on, the scene's screen wins
  React.useEffect(() => {
    if (replayActive) {
      const scene = SCENES[sceneIdx];
      if (scene && scene.screen !== current) setCurrent(scene.screen);
    }
    try { window.parent.postMessage({ slideIndexChanged: Object.keys(SCREENS).indexOf(current) }, "*"); } catch {}
  }, [replayActive, sceneIdx]);

  // keyboard navigation — arrows advance scenes in replay, rooms otherwise
  React.useEffect(() => {
    const keys = Object.keys(SCREENS);
    const onKey = (e) => {
      if (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA") return;
      if (replayActive) {
        if (e.key === "ArrowRight" || e.key === "ArrowDown" || e.key === "j" || e.key === "n") {
          e.preventDefault();
          setSceneIdx(i => Math.min(SCENES.length - 1, i + 1));
        } else if (e.key === "ArrowLeft" || e.key === "ArrowUp" || e.key === "k" || e.key === "p") {
          e.preventDefault();
          setSceneIdx(i => Math.max(0, i - 1));
        } else if (e.key === "Escape") {
          setReplayActive(false);
        }
      } else {
        const idx = keys.indexOf(current);
        if (e.key === "ArrowDown" || e.key === "j") {
          e.preventDefault();
          setCurrent(keys[(idx+1) % keys.length]);
        } else if (e.key === "ArrowUp" || e.key === "k") {
          e.preventDefault();
          setCurrent(keys[(idx-1+keys.length) % keys.length]);
        }
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [current, replayActive]);

  const screen = SCREENS[current] ? SCREENS[current](setCurrent, projectFilter, setProjectFilter) : <ScreenTodayV2 onGo={setCurrent} project={projectFilter} setProject={setProjectFilter} />;
  const scene  = SCENES[sceneIdx];

  window.__startReplay = () => { setReplayActive(false); setCurrent("today"); };

  return (
    <div
      className={"stage" + (replayActive ? " replay" : "")}
      data-scene={replayActive && scene ? scene.k : undefined}
    >
      <Sidebar current={current} onGo={(s) => { setReplayActive(false); setCurrent(s); }} />
      <main className="main">
        {replayActive && scene && <SceneFrame scene={scene} idx={sceneIdx} total={SCENES.length} />}
        {screen}
      </main>
      <GlobalAskBubble open={askOpen} onToggle={() => setAskOpen((value) => !value)} />
      {replayActive && (
        <ReplayDock
          scene={scene}
          idx={sceneIdx}
          total={SCENES.length}
          onPrev={() => setSceneIdx(i => Math.max(0, i - 1))}
          onNext={() => setSceneIdx(i => Math.min(SCENES.length - 1, i + 1))}
          onEnd={() => { setReplayActive(false); setCurrent("today"); }}
          onJump={(i) => setSceneIdx(i)}
        />
      )}
    </div>
  );
}

const GlobalAskBubble = ({ open, onToggle }) => (
  <div className={"global-ask-v4" + (open ? " is-open" : "")}>
    {open && (
      <section className="global-ask-panel-v4" aria-label="Ask the office">
        <div>
          <span>Ask the office</span>
          <button type="button" onClick={onToggle} aria-label="Close Ask">Close</button>
        </div>
        <textarea aria-label="Ask the office" placeholder="Ask about a job, bill, schedule, quote, or message..." />
        <div>
          {["What's blocking St Leonards?", "Show bill questions.", "What did we send Marco?"].map((prompt) => (
            <button type="button" key={prompt}>{prompt}</button>
          ))}
        </div>
      </section>
    )}
    <button className="global-ask-dot-v4" type="button" onClick={onToggle} aria-expanded={open} aria-label="Ask the office">
      Ask
    </button>
  </div>
);

const ProjectFilterBar = ({ value, onChange }) => {
  const active = PROJECT_FILTERS.find((p) => p.id === value) || PROJECT_FILTERS[0];
  return (
    <div className="project-filter-bar">
      <div>
        <div className="screen-eyebrow">Project filter</div>
        <b>{active.label}</b>
        <span>{active.meta}</span>
      </div>
      <div className="project-filter-pills">
        {PROJECT_FILTERS.map((p) => (
          <button
            key={p.id}
            className={p.id === value ? "is-active" : ""}
            type="button"
            onClick={() => onChange(p.id)}
          >
            {p.label}
          </button>
        ))}
      </div>
    </div>
  );
};

/* =========================================================
   SceneFrame — the three-fact narrator card at the top of every replay scene
   ========================================================= */
const SceneFrame = ({ scene, idx, total }) => (
  <div className="scene-frame">
    <div className="scene-frame-head">
      <span className="scene-frame-counter">Scene <b>{idx + 1}</b> / {total}</span>
      <span className="scene-frame-chapter">{scene.chapter}</span>
      <h2 className="scene-frame-title">{scene.title}</h2>
    </div>
    <div className="scene-frame-body">
      <div className="scene-frame-col">
        <div className="scene-frame-eyebrow did">What the office did</div>
        <div className="scene-frame-text">{scene.did}</div>
      </div>
      <div className="scene-frame-col is-action">
        <div className="scene-frame-eyebrow approve">Your move</div>
        <div className="scene-frame-text">{scene.approve}</div>
        {scene.action && (
          <button className="scene-frame-cta" type="button">
            <Icon name={scene.action.icon} size={14} color="#FBF8F2"/>
            <span>{scene.action.label}</span>
          </button>
        )}
      </div>
      <div className="scene-frame-col">
        <div className="scene-frame-eyebrow receipt">Receipt saved</div>
        <div className="scene-frame-text">{scene.receipt}</div>
      </div>
    </div>
  </div>
);

/* =========================================================
   ReplayDock — bottom-fixed controller for the guided path
   ========================================================= */
const ReplayDock = ({ scene, idx, total, onPrev, onNext, onEnd, onJump }) => (
  <div className="replay-dock">
    <div className="replay-dock-progress">
      {Array.from({length: total}).map((_, i) => (
        <button
          key={i}
          className={"replay-dot " + (i === idx ? "is-current" : i < idx ? "is-done" : "")}
          onClick={() => onJump(i)}
          title={SCENES[i].title}
        />
      ))}
    </div>
    <div className="replay-dock-body">
      <div className="replay-dock-where">
        <span className="screen-eyebrow" style={{color:"var(--ink-on-rail-3)"}}>Replay · Glenrose office day</span>
        <span className="replay-dock-title">{scene.title}</span>
      </div>
      <div className="replay-dock-controls">
        <button
          className="replay-btn ghost"
          onClick={onPrev}
          disabled={idx === 0}
        >
          ← Prev
        </button>
        <span className="replay-dock-count">{idx + 1} / {total}</span>
        {idx < total - 1 ? (
          <button className="replay-btn primary" onClick={onNext}>
            Next: {SCENES[idx+1].title} →
          </button>
        ) : (
          <button className="replay-btn primary" onClick={onEnd}>
            End replay
          </button>
        )}
        <button className="replay-btn ghost" onClick={onEnd}>Esc · exit</button>
      </div>
    </div>
  </div>
);

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
