import { useCallback, useEffect, useRef, useState } from "react";
import { MicIcon, PaperclipIcon, SquareIcon } from "lucide-react";
import {
  PromptInput,
  PromptInputButton,
  PromptInputFooter,
  PromptInputHeader,
  PromptInputSubmit,
  PromptInputTextarea,
  PromptInputTools,
  usePromptInputAttachments,
  type PromptInputMessage,
} from "@/components/ai-elements/prompt-input";
import { AttachmentCard } from "@/components/attachment-card";
import { cn } from "@/lib/utils";

function AttachmentChips() {
  const attachments = usePromptInputAttachments();

  if (attachments.files.length === 0) return null;

  return (
    <div className="min-w-0 w-full">
      <div
        className="scrollbar-slim flex min-w-0 max-w-full snap-x snap-proximity flex-nowrap items-stretch gap-2.5 overflow-x-auto overflow-y-hidden overscroll-x-contain pb-1.5 pr-1"
        aria-label="Archivos adjuntos"
      >
        {attachments.files.map((file) => (
          <div key={file.id} className="shrink-0 snap-start">
            <AttachmentCard
              file={file}
              compact
              onRemove={() => attachments.remove(file.id)}
            />
          </div>
        ))}
      </div>
    </div>
  );
}


function AttachButton() {
  const attachments = usePromptInputAttachments();

  return (
    <PromptInputButton
      type="button"
      onClick={attachments.openFileDialog}
      aria-label="Adjuntar archivo"
      tooltip="Adjuntar archivo"
    >
      <PaperclipIcon className="size-4" />
    </PromptInputButton>
  );
}

function formatSeconds(total: number) {
  const m = Math.floor(total / 60);
  const s = total % 60;
  return `${m}:${s.toString().padStart(2, "0")}`;
}

function VoiceButton() {
  const attachments = usePromptInputAttachments();
  const recorderRef = useRef<MediaRecorder | null>(null);
  const [recording, setRecording] = useState(false);
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    if (!recording) return;
    const timer = window.setInterval(() => setSeconds((s) => s + 1), 1000);
    return () => window.clearInterval(timer);
  }, [recording]);

  const stop = useCallback(() => {
    recorderRef.current?.stop();
    recorderRef.current = null;
    setRecording(false);
  }, []);

  const start = useCallback(async () => {
    try {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      const recorder = new MediaRecorder(stream);
      const chunks: BlobPart[] = [];
      recorder.ondataavailable = (event) => chunks.push(event.data);
      recorder.onstop = () => {
        stream.getTracks().forEach((track) => track.stop());
        const blob = new Blob(chunks, { type: recorder.mimeType || "audio/webm" });
        const file = new File([blob], `nota-de-voz-${Date.now()}.webm`, { type: blob.type });
        attachments.add([file]);
      };
      recorder.start();
      recorderRef.current = recorder;
      setSeconds(0);
      setRecording(true);
    } catch {
      setRecording(false);
    }
  }, [attachments]);

  return (
    <PromptInputButton
      onClick={() => (recording ? stop() : void start())}
      aria-label={recording ? "Detener grabación" : "Grabar nota de voz"}
      tooltip={recording ? "Detener grabación" : "Grabar nota de voz"}
      className={cn(recording && "bg-destructive/10 text-destructive")}
    >
      {recording ? <SquareIcon className="size-4" /> : <MicIcon className="size-4" />}
      {recording ? <span className="tabular-nums">{formatSeconds(seconds)}</span> : null}
    </PromptInputButton>
  );
}

export function ChatComposer({
  onSend,
  busy,
  onStop,
  draft,
  onDraftChange,
}: {
  onSend: (message: PromptInputMessage) => void | Promise<void>;
  busy: boolean;
  onStop: () => void;
  draft: string;
  onDraftChange: (value: string) => void;
}) {
  const handleSubmit = (message: PromptInputMessage) => {
    if (busy) return;
    if (!message.text.trim() && message.files.length === 0) return;
    const result = onSend(message);
    onDraftChange("");
    return result;
  };

  return (
    <PromptInput
      onSubmit={handleSubmit}
      multiple
      maxFiles={8}
      maxFileSize={25 * 1024 * 1024}
      className="rounded-2xl border-0 bg-card shadow-[var(--shadow-soft)] transition-shadow focus-within:shadow-[var(--shadow-lift)]"
      inputGroupClassName="rounded-2xl border-0 shadow-none ring-0 has-[[data-slot=input-group-control]:focus-visible]:ring-0"
    >
      <PromptInputHeader className="min-w-0 w-full flex-nowrap empty:hidden">
        <AttachmentChips />
      </PromptInputHeader>

      <PromptInputTextarea
        autoFocus
        value={draft}
        onChange={(event) => onDraftChange(event.currentTarget.value)}
        placeholder="Describe el espacio, las tiendas y las semanas a cotizar..."
        className="min-h-[3.25rem] text-[0.95rem]"
      />

      <PromptInputFooter>
        <PromptInputTools>
          <AttachButton />
          <VoiceButton />
        </PromptInputTools>

        <PromptInputSubmit
          {...(busy ? { status: "streaming" as const } : {})}
          onStop={onStop}
          className="rounded-lg"
        />
      </PromptInputFooter>
    </PromptInput>
  );
}
