import { useEffect, useRef, useState } from "react";
import { Monitor, Square, MousePointer2 } from "lucide-react";
import { useStore } from "../store";
import { startScreenCapture, type CaptureController, type CaptureResult, type CaptureQuality } from "../lib/screenCapture";
import { ZOOM_STYLES, type ZoomStyle } from "../lib/screencastZoom";

// Record the screen (preferring this tab) → upload as a video asset → drop it on the
// timeline at the playhead, carrying the captured screencast metadata so the renderer
// can drive the auto-zoom "explainer" camera. Mirrors VoiceRecorder's upload + place flow.
export function ScreenRecorder({ onClose }: { onClose: () => void }) {
  const projectId = useStore((s) => s.projectId);
  const addAsset = useStore((s) => s.addAsset);
  const [state, setState] = useState<"idle" | "recording" | "saving">("idle");
  const [elapsed, setElapsed] = useState(0);
  const [err, setErr] = useState("");
  const [quality, setQuality] = useState<CaptureQuality>("1440p");
  const [fps, setFps] = useState<30 | 60>(30);
  // how eagerly the explainer camera zooms — default "calm" so it commits to a few
  // meaningful shots instead of pushing in on every click
  const [cameraStyle, setCameraStyle] = useState<ZoomStyle>("calm");
  // default OFF: keep the user's REAL recorded cursor and only paint click effects on it
  const [animatedCursor, setAnimatedCursor] = useState(false);
  const ctrl = useRef<CaptureController | null>(null);
  const startedAt = useRef(0);
  const timer = useRef<ReturnType<typeof setInterval> | null>(null);

  const release = () => { ctrl.current?.cancel(); ctrl.current = null; };
  // teardown (unmount / Cancel / re-toggle): stop the timer and free the capture, discarding any in-flight take
  useEffect(() => () => { if (timer.current) clearInterval(timer.current); release(); }, []);

  async function start() {
    setErr("");
    try {
      const c = await startScreenCapture({ quality, frameRate: fps, animatedCursor, cameraStyle });
      ctrl.current = c;
      startedAt.current = Date.now();
      setState("recording");
      timer.current = setInterval(() => setElapsed(Date.now() - startedAt.current), 200);
      // if the user ends sharing via the browser UI, the controller auto-stops — but the
      // resulting CaptureResult is only delivered through our own stop(), so we don't await it here.
    } catch (e) {
      release();
      setErr(e instanceof Error && e.name === "NotAllowedError" ? "Screen-share permission denied." : "Couldn't start screen capture.");
    }
  }

  async function stop() {
    if (timer.current) clearInterval(timer.current);
    const c = ctrl.current;
    if (!c) { onClose(); return; }
    setState("saving");
    try {
      const result = await c.stop();
      ctrl.current = null;
      await upload(result);
    } catch (e) {
      setErr(e instanceof Error ? e.message : "Couldn't save the recording.");
      setState("idle");
    }
  }

  async function upload(result: CaptureResult) {
    if (!projectId || result.blob.size === 0) { onClose(); return; }
    try {
      const name = `Screen recording ${new Date().toLocaleTimeString()}.webm`;
      const measured = Math.max(500, Math.round(result.durationMs));
      const res = await fetch(`/api/projects/${projectId}/assets?name=${encodeURIComponent(name)}&kind=video&durationMs=${measured}`, { method: "POST", headers: { "Content-Type": result.blob.type || "video/webm" }, body: result.blob });
      const a = await res.json();
      if (!a.id) throw new Error(a.error || "upload failed");
      const asset = { ...a, kind: "video" as const, durationMs: measured, width: a.width || result.width, height: a.height || result.height };
      addAsset(asset);
      // place at the playhead exactly like an imported video; placeAsset returns the new clip id
      const newClipId = useStore.getState().placeAsset(asset.id, useStore.getState().playheadMs);
      // attach the captured screencast metadata so the explainer camera can render
      if (newClipId) useStore.getState().setScreencast(newClipId, result.screencast); // requires store.setScreencast
      onClose();
    } catch (e) {
      setErr(e instanceof Error ? e.message : "Couldn't save the recording.");
      setState("idle");
    }
  }

  const secs = (elapsed / 1000).toFixed(1);
  return (
    <div className="flex items-center gap-3 border-b border-border bg-surface-raised px-3 py-2 text-[13px]">
      <Monitor size={15} className={state === "recording" ? "text-destructive" : "text-primary"} />
      {state === "idle" && <><span className="text-fg">Record your screen — adds an auto-zoom explainer camera</span>
        <label className="flex items-center gap-1 text-fg-muted">Quality
          <select value={quality} onChange={(e) => setQuality(e.target.value as CaptureQuality)} className="rounded border border-border bg-surface px-1.5 py-0.5 text-[12px] text-fg">
            <option value="1080p">1080p</option>
            <option value="1440p">1440p</option>
            <option value="4k">4K Ultra HD</option>
          </select></label>
        <label className="flex items-center gap-1 text-fg-muted">FPS
          <select value={fps} onChange={(e) => setFps(Number(e.target.value) as 30 | 60)} className="rounded border border-border bg-surface px-1.5 py-0.5 text-[12px] text-fg">
            <option value={30}>30</option>
            <option value={60}>60</option>
          </select></label>
        <label className="flex items-center gap-1 text-fg-muted" title={ZOOM_STYLES.find((s) => s.id === cameraStyle)?.hint}>Camera
          <select value={cameraStyle} onChange={(e) => setCameraStyle(e.target.value as ZoomStyle)} className="rounded border border-border bg-surface px-1.5 py-0.5 text-[12px] text-fg">
            {ZOOM_STYLES.map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}
          </select></label>
        <button onClick={() => setAnimatedCursor((v) => !v)} title="Replace the real cursor with a smooth animated one (avoids a double cursor)" className={`flex items-center gap-1 rounded-md border px-2 py-1 text-[12px] ${animatedCursor ? "border-primary text-primary" : "border-border text-fg-muted"}`}>
          <MousePointer2 size={12} /> Animated cursor</button>
        <button onClick={start} className="rounded-md bg-primary px-2.5 py-1 text-[12px] font-semibold text-white hover:brightness-105">Start</button></>}
      {state === "recording" && <>
        <span className="flex items-center gap-1.5 text-fg"><span className="h-2 w-2 animate-pulse rounded-full bg-destructive" /> Recording <span className="num">{secs}s</span></span>
        <button onClick={stop} className="flex items-center gap-1 rounded-md bg-destructive px-2.5 py-1 text-[12px] font-semibold text-white hover:brightness-110"><Square size={11} /> Stop &amp; place</button></>}
      {state === "saving" && <span className="text-fg-subtle">Saving…</span>}
      {err && <span className="text-[12px] text-destructive">{err}</span>}
      <div className="flex-1" />
      <button onClick={onClose} className="rounded border border-border px-2 py-1 text-[11px] text-fg-muted hover:text-fg">{state === "recording" ? "Cancel" : "Close"}</button>
    </div>
  );
}
