"use client";

import { useEffect, useRef, useState } from "react";
import { IconMic, IconShare, IconVideo, IconX } from "./icons";

type ClipKind = "voice" | "camera" | "screen";

/**
 * In-composer recorder for voice and video clips (features 5.5–5.6).
 * Produces a File the existing upload path already knows how to send.
 */
export function ClipRecorder({
  onComplete,
  onCancel,
}: {
  onComplete: (file: File) => void;
  onCancel: () => void;
}) {
  const [kind, setKind] = useState<ClipKind | null>(null);
  const [elapsed, setElapsed] = useState(0);
  const [error, setError] = useState<string | null>(null);
  const onCompleteRef = useRef(onComplete);
  onCompleteRef.current = onComplete;
  const mediaRef = useRef<MediaStream | null>(null);
  const recorderRef = useRef<MediaRecorder | null>(null);
  const chunksRef = useRef<Blob[]>([]);
  const videoRef = useRef<HTMLVideoElement | null>(null);

  useEffect(() => {
    if (!kind) return;
    let cancelled = false;
    const started = Date.now();
    const tick = window.setInterval(() => setElapsed(Math.round((Date.now() - started) / 1000)), 250);

    async function start() {
      try {
        const stream =
          kind === "voice"
            ? await navigator.mediaDevices.getUserMedia({ audio: true })
            : kind === "camera"
              ? await navigator.mediaDevices.getUserMedia({ audio: true, video: { width: 1280, height: 720 } })
              : await navigator.mediaDevices.getDisplayMedia({ video: true, audio: true });
        if (cancelled) {
          for (const track of stream.getTracks()) track.stop();
          return;
        }
        mediaRef.current = stream;
        if (videoRef.current && kind !== "voice") {
          videoRef.current.srcObject = stream;
          void videoRef.current.play().catch(() => undefined);
        }
        const mime =
          kind === "voice"
            ? pickMime(["audio/webm;codecs=opus", "audio/webm", "audio/mp4"])
            : pickMime(["video/webm;codecs=vp9,opus", "video/webm", "video/mp4"]);
        const recorder = new MediaRecorder(stream, mime ? { mimeType: mime } : undefined);
        chunksRef.current = [];
        recorder.ondataavailable = (event) => {
          if (event.data.size > 0) chunksRef.current.push(event.data);
        };
        recorder.onstop = () => {
          const type = recorder.mimeType || (kind === "voice" ? "audio/webm" : "video/webm");
          const blob = new Blob(chunksRef.current, { type });
          const ext = type.includes("mp4") ? (kind === "voice" ? "m4a" : "mp4") : "webm";
          const file = new File([blob], `${kind}-clip-${Date.now()}.${ext}`, { type });
          onCompleteRef.current(file);
        };
        recorderRef.current = recorder;
        recorder.start(200);
      } catch (err) {
        setError(err instanceof Error ? err.message : "Could not start recording");
        setKind(null);
      }
    }

    void start();
    return () => {
      cancelled = true;
      window.clearInterval(tick);
      const recorder = recorderRef.current;
      if (recorder) recorder.onstop = null;
      if (recorder?.state === "recording") recorder.stop();
      mediaRef.current?.getTracks().forEach((track: MediaStreamTrack) => track.stop());
    };
  }, [kind]);

  function stop() {
    const recorder = recorderRef.current;
    if (recorder && recorder.state !== "inactive") recorder.stop();
    mediaRef.current?.getTracks().forEach((track: MediaStreamTrack) => track.stop());
  }

  if (!kind) {
    return (
      <div className="clip-recorder">
        <button type="button" onClick={() => setKind("voice")} title="Voice clip">
          <IconMic size={15} /> Voice
        </button>
        <button type="button" onClick={() => setKind("camera")} title="Camera clip">
          <IconVideo size={15} /> Camera
        </button>
        <button type="button" onClick={() => setKind("screen")} title="Screen clip">
          <IconShare size={15} /> Screen
        </button>
        <button type="button" aria-label="Cancel" onClick={onCancel}>
          <IconX size={14} />
        </button>
        {error && <span>{error}</span>}
      </div>
    );
  }

  return (
    <div className="clip-recorder live">
      <span className="clip-dot" />
      <span>
        Recording {kind} · {elapsed}s
      </span>
      {kind !== "voice" && <video ref={videoRef} muted playsInline />}
      <button type="button" onClick={stop}>
        Stop & attach
      </button>
      <button
        type="button"
        onClick={() => {
          const recorder = recorderRef.current;
          if (recorder) recorder.onstop = null;
          if (recorder?.state === "recording") recorder.stop();
          mediaRef.current?.getTracks().forEach((track: MediaStreamTrack) => track.stop());
          recorderRef.current = null;
          setKind(null);
          onCancel();
        }}
      >
        Discard
      </button>
    </div>
  );
}

function pickMime(candidates: string[]): string | undefined {
  if (typeof MediaRecorder === "undefined" || !MediaRecorder.isTypeSupported) return undefined;
  return candidates.find((type) => MediaRecorder.isTypeSupported(type));
}
