"use client";

import { useEffect, useState } from "react";
import { toast } from "sonner";
import { Check, Copy, Sparkles } from "lucide-react";

import { colorModeFromTheme } from "@/components/theme/use-dark-theme";

import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { MarkdownPreview } from "@/components/markdown/markdown-widgets";
import { ChatMessageList, ChatComposer, type ChatBubbleMessage } from "@/components/ai/chat-thread";
import { useSpeechRecognition } from "@/hooks/use-speech-recognition";
import {
  converseAboutGroupStatus,
  type StatusChatMessage,
} from "@/lib/actions/group-status-ai";
import type { GroupDTO } from "@/types/board";

export function StatusUpdateDialog({
  group,
  open,
  onOpenChange,
}: {
  group: GroupDTO;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}) {
  const colorMode = colorModeFromTheme();

  // The generated summary, shown permanently once produced -- there's no
  // accept/discard step, since nothing here is ever saved back to the
  // group's notes (export-only, by design).
  const [summary, setSummary] = useState<string | null>(null);
  const [generating, setGenerating] = useState(false);
  const [copied, setCopied] = useState(false);
  const [messages, setMessages] = useState<StatusChatMessage[]>([]);
  const [input, setInput] = useState("");
  const [sending, setSending] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const { supported: micSupported, listening, start, stop } = useSpeechRecognition({
    onFinalResult: (transcript) =>
      setInput((prev) => (prev ? `${prev} ${transcript}` : transcript)),
    onError: setError,
  });

  // Fires the initial summary the moment the dialog opens -- no user
  // action needed, per spec. Guarded by summary === null so it doesn't
  // re-fire on every re-render while open, and skipped once a summary (or
  // an error in its place) already exists for this open session.
  useEffect(() => {
    if (!open || summary !== null || generating) return;
    let cancelled = false;
    setGenerating(true);
    setError(null);
    converseAboutGroupStatus(group.id, []).then((result) => {
      if (cancelled) return;
      setGenerating(false);
      if ("error" in result) {
        setError(result.error);
        return;
      }
      setSummary(result.content);
    });
    return () => {
      cancelled = true;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  // Starts fresh every time it's reopened -- matches GroupAiDialog/
  // TodoAiDialog's existing behavior.
  function handleOpenChange(next: boolean) {
    if (!next) {
      stop();
      setSummary(null);
      setGenerating(false);
      setCopied(false);
      setMessages([]);
      setInput("");
      setError(null);
    }
    onOpenChange(next);
  }

  async function handleCopy() {
    if (!summary) return;
    try {
      await navigator.clipboard.writeText(summary);
      setCopied(true);
      toast.success("Copied to clipboard.");
      setTimeout(() => setCopied(false), 2000);
    } catch {
      toast.error("Couldn't copy to clipboard.");
    }
  }

  async function handleSend() {
    const text = input.trim();
    if (!text || sending) return;
    if (listening) stop();

    const next: StatusChatMessage[] = [...messages, { role: "user", content: text }];
    setMessages(next);
    setInput("");
    setError(null);
    setSending(true);
    const result = await converseAboutGroupStatus(group.id, next);
    setSending(false);

    if ("error" in result) {
      setError(result.error);
      return;
    }
    setMessages([...next, { role: "assistant", content: result.content }]);
  }

  return (
    <Dialog open={open} onOpenChange={handleOpenChange}>
      <DialogContent className="flex max-h-[80vh] flex-col sm:max-w-lg" data-color-mode={colorMode}>
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Sparkles className="size-4 text-primary" />
            Status Update — {group.title}
          </DialogTitle>
        </DialogHeader>

        {generating && !summary && (
          <p className="rounded-md border border-dashed p-8 text-center text-sm text-muted-foreground">
            Generating status update…
          </p>
        )}

        {error && !summary && (
          <p className="text-sm text-destructive">{error}</p>
        )}

        {summary && (
          <div className="flex min-h-0 flex-1 flex-col gap-3 overflow-hidden">
            <div className="max-h-[35vh] shrink-0 overflow-y-auto rounded-md border p-4">
              <MarkdownPreview source={summary} />
            </div>
            <Button
              type="button"
              variant="outline"
              size="sm"
              className="w-fit gap-2"
              onClick={handleCopy}
            >
              {copied ? <Check className="size-4" /> : <Copy className="size-4" />}
              {copied ? "Copied" : "Copy to clipboard"}
            </Button>

            <div className="flex min-h-0 flex-1 flex-col gap-3 overflow-hidden">
              <ChatMessageList
                messages={messages as ChatBubbleMessage[]}
                sending={sending}
                error={error}
                emptyHint="Ask a follow-up question about this group."
                colorMode={colorMode}
              />
              <ChatComposer
                value={input}
                onChange={setInput}
                onSend={handleSend}
                sending={sending}
                listening={listening}
                micSupported={micSupported}
                onStartListening={start}
                onStopListening={stop}
              />
            </div>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
