/* Live launcher — overlay that lets users actually drive the pipeline
   end-to-end against the real API:
   - Submit a concept → POST /api/pipeline/run
   - See cost estimate + validation gate
   - Approve preview render ($10 cap) or full render ($150 cap)
   - Live-poll batch status with progress bars
   - Trigger export when assets land

   The existing 14 design screens still render the SAMPLE fixtures alongside.
   This overlay is the bridge from "clickable prototype" to "working product"
   while we incrementally wire each screen to the API. */

const { useEffect, useState, useCallback } = React;

const LiveLauncher = () => {
  const [open, setOpen]       = useState(false);
  const [step, setStep]       = useState('idle'); // idle | running | review | preview-render | preview-done | full-render | full-done | export
  const [concept, setConcept] = useState('A night-shift nurse keeps hearing a child humming inside a locked hospital room that was demolished years ago.');
  const [title, setTitle]     = useState('Room 4B');
  const [run, setRun]         = useState(null);
  const [batch, setBatch]     = useState(null);
  const [jobs, setJobs]       = useState([]);
  const [exportInfo, setExportInfo] = useState(null);
  const [error, setError]     = useState(null);

  const reset = () => {
    setStep('idle'); setRun(null); setBatch(null); setJobs([]);
    setExportInfo(null); setError(null);
  };

  const submit = useCallback(async () => {
    setError(null); setStep('running');
    try {
      const result = await window.CinematonAPI.runPipeline({ concept, title });
      setRun(result);
      setStep('review');
      // Notify the app shell so all 14 screens swap to live data.
      window.dispatchEvent(new CustomEvent('cinematon:live-run', { detail: { project_id: result.project.id } }));
    } catch (err) { setError(err); setStep('idle'); }
  }, [concept, title]);

  const approvePreview = async () => {
    if (!run) return;
    setError(null); setStep('preview-render');
    try {
      const r = await window.CinematonAPI.approve(run.project.id, {
        acknowledgement_text: window.CinematonAPI.ACK_PREVIEW, kind: 'preview',
      });
      setBatch(r.batch); setJobs(r.jobs);
      window.dispatchEvent(new CustomEvent('cinematon:live-batch', { detail: { batch_id: r.batch.id } }));
    } catch (err) { setError(err); setStep('review'); }
  };

  const approveFull = async () => {
    if (!run) return;
    setError(null); setStep('full-render');
    try {
      const r = await window.CinematonAPI.approve(run.project.id, {
        acknowledgement_text: window.CinematonAPI.ACK_FULL, kind: 'full',
      });
      setBatch(r.batch); setJobs(r.jobs);
      window.dispatchEvent(new CustomEvent('cinematon:live-batch', { detail: { batch_id: r.batch.id, kind: 'full' } }));
    } catch (err) { setError(err); setStep('preview-done'); }
  };

  const exportProject = async () => {
    if (!run) return;
    setStep('export');
    try {
      const info = await window.CinematonAPI.exportProject(run.project.id);
      setExportInfo(info);
    } catch (err) { setError(err); }
  };

  // Live-poll the active batch.
  useEffect(() => {
    if (!batch) return;
    const stop = window.CinematonAPI.pollBatch(batch.id, {
      onUpdate: (j) => {
        if (!j) return;
        setJobs(j);
        if (j.every((x) => ['complete','failed','cancelled'].includes(x.status))) {
          setStep((s) => (s === 'preview-render' ? 'preview-done' : s === 'full-render' ? 'full-done' : s));
        }
      },
    });
    return stop;
  }, [batch]);

  // Show a "● LIVE" indicator and open hotkey when API is reachable.
  const [live, setLive] = useState(false);
  useEffect(() => {
    setLive(Boolean(window.CinematonAPI?.live));
    const onLive = () => setLive(true);
    const onOpen = () => { reset(); setOpen(true); };
    window.addEventListener('cinematon:live', onLive);
    window.addEventListener('cinematon:open-launcher', onOpen);
    return () => {
      window.removeEventListener('cinematon:live', onLive);
      window.removeEventListener('cinematon:open-launcher', onOpen);
    };
  }, []);

  if (!live) return null;

  // The floating launch button is gone — the titlebar's "+ New Project" button
  // dispatches `cinematon:open-launcher` which we listen for above. We render
  // ONLY the modal here.

  return (
    <>
      {open && (
        <div className="ll-overlay" role="dialog" aria-modal="true">
          <div className="ll-modal">
            <div className="ll-head">
              <span className="ll-title">Cinematon · Live pipeline</span>
              <button className="ll-close" onClick={() => { setOpen(false); reset(); }}>✕</button>
            </div>

            {step === 'idle' && (
              <div className="ll-body">
                <label className="ll-label">Project title</label>
                <input className="ll-input" value={title} onChange={(e) => setTitle(e.target.value)} />
                <label className="ll-label">Concept (one paragraph)</label>
                <textarea
                  className="ll-textarea" rows={5}
                  value={concept} onChange={(e) => setConcept(e.target.value)}
                />
                <div className="ll-actions">
                  <button className="ll-btn primary" onClick={submit} disabled={concept.length < 12}>
                    Run pipeline →
                  </button>
                </div>
              </div>
            )}

            {step === 'running' && (
              <div className="ll-body ll-loading">
                <div className="ll-spinner"/>
                <div>Running concept → brief → bible → outline → scenes → screenplay → shots → prompts → cost estimate…</div>
                <div className="ll-dim">No paid API calls yet. This run uses the agent fixtures unless ANTHROPIC_API_KEY is set on the server.</div>
              </div>
            )}

            {(step === 'review' || step === 'preview-done') && run && (
              <div className="ll-body">
                <div className="ll-row">
                  <span className="ll-pill">project_id</span>
                  <code>{run.project.id}</code>
                </div>
                <div className="ll-grid">
                  <Stat label="Shots" value={run.shots.length}/>
                  <Stat label="Estimated runtime" value={`${run.shots.reduce((a,s)=>a+s.duration_seconds,0)}s`}/>
                  <Stat label="Estimated cost" value={`$${run.cost_estimate.estimated_total_cost_usd.toFixed(2)}`} accent/>
                  <Stat label="Validation"
                    value={run.validation.blocks_render ? 'BLOCKING' : 'OK'}
                    bad={run.validation.blocks_render}/>
                </div>
                {run.validation.blocks_render && (
                  <div className="ll-block">
                    <div className="ll-block-title">Validation blocks full render:</div>
                    <ul>
                      {run.validation.blocking_reasons.map((r, i) => <li key={i}>{r}</li>)}
                    </ul>
                  </div>
                )}
                <div className="ll-actions">
                  {step === 'review' && (
                    <button className="ll-btn" onClick={approvePreview}>Approve preview render (≤$10)</button>
                  )}
                  <button className="ll-btn primary" onClick={approveFull}
                    disabled={run.validation.blocks_render || run.cost_estimate.estimated_total_cost_usd > 150}
                    title={run.validation.blocks_render ? 'Validation blocks render' : ''}>
                    Approve full render (${run.cost_estimate.estimated_total_cost_usd.toFixed(2)} / $150)
                  </button>
                </div>
              </div>
            )}

            {(step === 'preview-render' || step === 'full-render' || step === 'preview-done' || step === 'full-done') && jobs.length > 0 && (
              <div className="ll-body">
                <div className="ll-section">{step.startsWith('preview') ? 'Preview render' : 'Full render'}</div>
                <table className="ll-jobs">
                  <thead><tr><th>shot</th><th>status</th><th>progress</th><th>asset</th></tr></thead>
                  <tbody>
                    {jobs.map((j) => (
                      <tr key={j.id}>
                        <td><code>{j.shot_id}</code></td>
                        <td className={`ll-status ll-${j.status}`}>{j.status}</td>
                        <td>
                          <div className="ll-prog"><div className="ll-prog-fill" style={{width:`${(j.progress*100).toFixed(0)}%`}}/></div>
                        </td>
                        <td>{j.asset_id ? <code>{j.asset_id}</code> : <span className="ll-dim">—</span>}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
                {step === 'full-done' && (
                  <div className="ll-actions">
                    <button className="ll-btn primary" onClick={exportProject}>Export project package →</button>
                  </div>
                )}
              </div>
            )}

            {step === 'export' && (
              <div className="ll-body">
                {exportInfo ? (
                  <>
                    <div>Export bundled.</div>
                    <div className="ll-export">
                      <code>{exportInfo.zip_path}</code>
                      <div className="ll-dim">SHA256: {exportInfo.sha256.slice(0, 16)}…</div>
                      <div className="ll-actions">
                        <a className="ll-btn primary" href={exportInfo.download_url}>Download .zip</a>
                      </div>
                    </div>
                  </>
                ) : <div className="ll-loading"><div className="ll-spinner"/>Bundling…</div>}
              </div>
            )}

            {error && <div className="ll-error">{error.message || String(error)}{error.body && <pre>{JSON.stringify(error.body, null, 2)}</pre>}</div>}
          </div>
        </div>
      )}
    </>
  );
};

const Stat = ({ label, value, accent, bad }) => (
  <div className={`ll-stat${accent ? ' accent' : ''}${bad ? ' bad' : ''}`}>
    <div className="ll-stat-lbl">{label}</div>
    <div className="ll-stat-val">{value}</div>
  </div>
);

window.LiveLauncher = LiveLauncher;
