import { useEffect, useRef, useState } from "react";
import { useChat } from "@ai-sdk/react";
import { DefaultChatTransport } from "ai";
import { MessageSquare, X, RotateCcw, ThumbsUp, ThumbsDown } from "lucide-react";
import { Conversation, ConversationContent } from "@/components/ai-elements/conversation";
import { Message, MessageContent, MessageResponse } from "@/components/ai-elements/message";
import {
  PromptInput,
  PromptInputTextarea,
  PromptInputFooter,
  PromptInputSubmit,
} from "@/components/ai-elements/prompt-input";
import { Shimmer } from "@/components/ai-elements/shimmer";
import { Button } from "@/components/ui/button";
import { submitChatFeedback } from "@/lib/chatbot.functions";
import logo from "@/assets/gatavase-logo.png.asset.json";

export const GATAVASE_CHAT_EVENT = "gatavase:open-chat";

export function openGatavaseChat() {
  window.dispatchEvent(new CustomEvent(GATAVASE_CHAT_EVENT));
}

const SUGGESTIONS = [
  "What services does Gatavase offer?",
  "Can you build a mobile app for my business?",
  "How do I request a demo?",
];

export function GatavaseChat() {
  const [open, setOpen] = useState(false);
  const [chatKey, setChatKey] = useState(0);

  useEffect(() => {
    const handler = () => setOpen(true);
    window.addEventListener(GATAVASE_CHAT_EVENT, handler);
    return () => window.removeEventListener(GATAVASE_CHAT_EVENT, handler);
  }, []);

  return (
    <>
      <button
        type="button"
        onClick={() => setOpen((v) => !v)}
        aria-label={open ? "Close Gatavase AI chat" : "Open Gatavase AI chat"}
        className="fixed right-5 bottom-5 z-50 grid size-14 place-items-center rounded-full bg-primary text-primary-foreground shadow-lg transition-transform hover:scale-105"
      >
        {open ? <X className="size-6" /> : <MessageSquare className="size-6" />}
      </button>

      {open ? (
        <div className="panel fixed right-4 bottom-24 z-50 flex h-[min(70vh,560px)] w-[min(400px,calc(100vw-2rem))] flex-col overflow-hidden rounded-xl border border-border bg-background shadow-2xl">
          <header className="flex items-center gap-3 border-b border-border px-4 py-3">
            <img src={logo.url} alt="" width={28} height={28} className="size-7 rounded-md" />
            <div className="min-w-0">
              <p className="text-sm font-semibold">Gatavase AI</p>
              <p className="truncate text-xs text-muted-foreground">
                Ask about our services & products
              </p>
            </div>
            <Button
              variant="ghost"
              size="icon-sm"
              className="ml-auto"
              aria-label="Start a new conversation"
              onClick={() => setChatKey((k) => k + 1)}
            >
              <RotateCcw className="size-4" />
            </Button>
          </header>
          <ChatWindow key={chatKey} />
        </div>
      ) : null}
    </>
  );
}

function ChatWindow() {
  const [input, setInput] = useState("");
  const textareaRef = useRef<HTMLTextAreaElement>(null);
  const { messages, sendMessage, status, error } = useChat({
    transport: new DefaultChatTransport({ api: "/api/chat" }),
  });

  const busy = status === "submitted" || status === "streaming";

  useEffect(() => {
    if (!busy) textareaRef.current?.focus();
  }, [busy]);

  function send(text: string) {
    const value = text.trim();
    if (!value || busy) return;
    setInput("");
    void sendMessage({ text: value });
  }

  return (
    <>
      <Conversation className="flex-1">
        <ConversationContent className="gap-4 p-4">
          {messages.length === 0 ? (
            <div className="space-y-3 text-sm text-muted-foreground">
              <p>
                Hello 👋 I'm Gatavase AI. Ask me about our services, products, process or how to get
                a project started.
              </p>
              <div className="flex flex-col gap-2">
                {SUGGESTIONS.map((s) => (
                  <button
                    key={s}
                    type="button"
                    onClick={() => send(s)}
                    className="rounded-md border border-border px-3 py-2 text-left text-xs transition-colors hover:border-primary hover:text-foreground"
                  >
                    {s}
                  </button>
                ))}
              </div>
            </div>
          ) : null}

          {messages.map((message, index) => {
            const text = message.parts
              .map((part) => (part.type === "text" ? part.text : ""))
              .join("");
            if (!text) return null;
            const previous = messages[index - 1];
            const question =
              message.role === "assistant" && previous
                ? previous.parts.map((p) => (p.type === "text" ? p.text : "")).join("")
                : undefined;
            return (
              <Message from={message.role} key={message.id}>
                <MessageContent>
                  <MessageResponse>{text}</MessageResponse>
                  {message.role === "assistant" && !busy ? (
                    <AnswerFeedback messageRef={message.id} question={question} answer={text} />
                  ) : null}
                </MessageContent>
              </Message>
            );
          })}

          {status === "submitted" ? <Shimmer className="text-sm">Thinking…</Shimmer> : null}
          {error ? (
            <p className="text-xs text-destructive">
              The assistant is unavailable right now. Please email
              gazmanadvancedtechnologies@gmail.com.
            </p>
          ) : null}
        </ConversationContent>
      </Conversation>

      <div className="border-t border-border p-3">
        <PromptInput
          onSubmit={(_message, event) => {
            event.preventDefault();
            send(input);
          }}
        >
          <PromptInputTextarea
            ref={textareaRef}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            placeholder="Ask Gatavase AI…"
            autoFocus
          />
          <PromptInputFooter className="justify-end">
            <PromptInputSubmit status={status} disabled={busy || !input.trim()} />
          </PromptInputFooter>
        </PromptInput>
      </div>
    </>
  );
}

function AnswerFeedback({
  messageRef,
  question,
  answer,
}: {
  messageRef: string;
  question?: string;
  answer: string;
}) {
  const [sent, setSent] = useState<"up" | "down" | null>(null);

  async function rate(rating: "up" | "down") {
    if (sent) return;
    setSent(rating);
    try {
      await submitChatFeedback({ data: { rating, question, answer, messageRef } });
    } catch {
      /* feedback is best-effort */
    }
  }

  return (
    <div className="mt-2 flex items-center gap-1 text-muted-foreground">
      {sent ? (
        <span className="text-xs">Thanks for the feedback.</span>
      ) : (
        <>
          <button
            type="button"
            aria-label="This answer was helpful"
            onClick={() => rate("up")}
            className="rounded p-1 transition-colors hover:text-primary"
          >
            <ThumbsUp className="size-3.5" />
          </button>
          <button
            type="button"
            aria-label="This answer was not helpful"
            onClick={() => rate("down")}
            className="rounded p-1 transition-colors hover:text-destructive"
          >
            <ThumbsDown className="size-3.5" />
          </button>
        </>
      )}
    </div>
  );
}
