// frontend/components/inbox/CaptureComposer.tsx
"use client";
import { useRef, useState } from "react";
import { Icon } from "@/components/Icon";
import { transcribeAudio, captionImage } from "@/lib/inbox/multimodal";

// 멀티모달 미가용/거부 시 phase-4 톤 폴백 (graceful degrade)
const VOICE_FALLBACK = "음성 메모 — (텍스트로 적어주세요)";
const IMAGE_FALLBACK = "이미지 캡처 — (자동 인식 결과 없음)";

export default function CaptureComposer({
  onSubmit,
}: {
  onSubmit: (raw: string, kind: "text" | "voice" | "image") => void;
}) {
  const [input, setInput] = useState("");
  const [recording, setRecording] = useState(false);
  const recRef = useRef<MediaRecorder | null>(null);
  const fileRef = useRef<HTMLInputElement | null>(null);

  const submitText = () => {
    const t = input.trim();
    if (!t) return;
    onSubmit(t, "text");
    setInput("");
  };

  /* 음성: 실제 녹음 → /inbox/transcribe → raw 텍스트로 capture */
  const toggleMic = async () => {
    if (recording) {
      recRef.current?.stop();
      return;
    }
    if (!navigator.mediaDevices?.getUserMedia) {
      onSubmit(VOICE_FALLBACK, "voice");
      return;
    }
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const rec = new MediaRecorder(stream);
      const chunks: Blob[] = [];
      rec.ondataavailable = (e) => chunks.push(e.data);
      rec.onstop = async () => {
        stream.getTracks().forEach((t) => t.stop());
        setRecording(false);
        const blob = new Blob(chunks, { type: "audio/webm" });
        try {
          const { text } = await transcribeAudio(blob);
          onSubmit(text || VOICE_FALLBACK, "voice");
        } catch {
          onSubmit(VOICE_FALLBACK, "voice");
        }
      };
      recRef.current = rec;
      rec.start();
      setRecording(true);
    } catch {
      onSubmit(VOICE_FALLBACK, "voice"); // 권한 거부 → 폴백
    }
  };

  /* 이미지: 파일 선택 → /inbox/caption → raw 캡션으로 capture */
  const onImage = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const f = e.target.files?.[0];
    if (!f) return;
    try {
      const { text } = await captionImage(f);
      onSubmit(text || IMAGE_FALLBACK, "image");
    } catch {
      onSubmit(IMAGE_FALLBACK, "image");
    } finally {
      e.target.value = "";
    }
  };

  return (
    <div className="sb-cmd">
      <Icon name="spark" />
      <input
        value={input}
        onChange={(e) => setInput(e.target.value)}
        onKeyDown={(e) => e.key === "Enter" && submitText()}
        placeholder="갑자기 생각난 것 아무거나… 예) 다음 주 한국 가는 비행기 티켓 사기"
        aria-label="인박스에 빠르게 캡처"
      />
      <button
        className={"sb-mode" + (recording ? " rec" : "")}
        onClick={toggleMic}
        aria-label={recording ? "녹음 중지" : "음성으로 캡처"}
        aria-pressed={recording}
      >
        <Icon name="mic" />
      </button>
      <button
        className="sb-mode"
        onClick={() => fileRef.current?.click()}
        aria-label="이미지로 캡처"
      >
        <Icon name="image" />
      </button>
      <input ref={fileRef} type="file" accept="image/*" hidden onChange={onImage} />
      <button className="sb-send" onClick={submitText} aria-label="보내기">
        <Icon name="arrow" />
      </button>
    </div>
  );
}
