"use client";

import { useEffect, useMemo, useRef, useState } from "react";

// eslint-disable-next-line @typescript-eslint/no-explicit-any
type SpeechRecognitionInstance = any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type SpeechRecognitionConstructor = new () => SpeechRecognitionInstance;

type ChatMessage = {
  role: "user" | "assistant";
  content: string;
  timestamp: number;
};

type ApiResponse = {
  response: string;
  shouldCaptureEmail: boolean;
  suggestedActions: string[];
};

type SiteMenteVoiceWidgetProps = {
  initialLang?: "es" | "en";
};

const quickActions = {
  es: [
    { label: "¿Cuánto cuesta?", icon: "💰" },
    { label: "Ver casos de éxito", icon: "🎯" },
    { label: "¿Cómo funciona?", icon: "⚙️" },
  ],
  en: [
    { label: "Pricing?", icon: "💰" },
    { label: "Success stories", icon: "🎯" },
    { label: "How it works?", icon: "⚙️" },
  ],
} as const;

const initialGreeting = {
  es: "Hola, soy el cerebro de SiteMente. ¿En qué te puedo ayudar hoy?",
  en: "Hi, I'm the SiteMente brain. How can I help you today?",
} as const;

export default function SiteMenteVoiceWidget({
  initialLang = "es",
}: SiteMenteVoiceWidgetProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [lang, setLang] = useState<"es" | "en">(initialLang);
  const [messages, setMessages] = useState<ChatMessage[]>([
    {
      role: "assistant",
      content: initialGreeting[initialLang],
      timestamp: Date.now(),
    },
  ]);
  const [input, setInput] = useState("");
  const [voiceMode, setVoiceMode] = useState(true);
  const [isRecording, setIsRecording] = useState(false);
  const [isSpeaking, setIsSpeaking] = useState(false);
  const [isLoading, setIsLoading] = useState(false);
  const [transcript, setTranscript] = useState("");
  const [speechSupported, setSpeechSupported] = useState(true);
  const [showTooltip, setShowTooltip] = useState(false);

  const recognitionRef = useRef<SpeechRecognitionInstance | null>(null);
  const isRecordingRef = useRef(false);
  const transcriptRef = useRef("");
  const messagesEndRef = useRef<HTMLDivElement | null>(null);

  const localeLabel = useMemo(
    () => (lang === "es" ? "ES" : "EN"),
    [lang]
  );

  useEffect(() => {
    setLang(initialLang);
  }, [initialLang]);

  useEffect(() => {
    const seen = window.localStorage.getItem("sitemente:voice-tooltip");
    if (!seen) {
      setShowTooltip(true);
      window.localStorage.setItem("sitemente:voice-tooltip", "1");
      const timeout = window.setTimeout(() => setShowTooltip(false), 4000);
      return () => window.clearTimeout(timeout);
    }
    return undefined;
  }, []);

  useEffect(() => {
    isRecordingRef.current = isRecording;
  }, [isRecording]);

  useEffect(() => {
    transcriptRef.current = transcript;
  }, [transcript]);

  useEffect(() => {
    const SpeechRecognitionImpl =
      typeof window !== "undefined"
        ? ((window as typeof window & {
            webkitSpeechRecognition?: SpeechRecognitionConstructor;
          }).SpeechRecognition ||
            (window as typeof window & {
              webkitSpeechRecognition?: SpeechRecognitionConstructor;
            }).webkitSpeechRecognition)
        : undefined;

    if (!SpeechRecognitionImpl) {
      setSpeechSupported(false);
      return;
    }

    const recognition = new SpeechRecognitionImpl();
    recognition.lang = lang === "es" ? "es-ES" : "en-US";
    recognition.interimResults = true;
    recognition.continuous = false;

    recognition.onresult = (event) => {
      const result = Array.from(event.results)
        .map((res) => res[0]?.transcript ?? "")
        .join(" ");
      setTranscript(result.trim());
    };

    recognition.onerror = () => {
      setIsRecording(false);
    };

    recognition.onend = () => {
      if (isRecordingRef.current) {
        setIsRecording(false);
        const finalTranscript = transcriptRef.current.trim();
        if (finalTranscript) {
          handleSend(finalTranscript);
        }
        setTranscript("");
      }
    };

    recognitionRef.current = recognition;
  }, [lang]);

  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages, isOpen]);

  useEffect(() => {
    if (!isSpeaking) return;
    return () => {
      window.speechSynthesis?.cancel();
    };
  }, [isSpeaking]);

  useEffect(() => {
    setMessages((prev) => {
      if (prev.length === 0) return prev;
      const updated = [...prev];
      if (updated[0].role === "assistant") {
        updated[0] = {
          ...updated[0],
          content: initialGreeting[lang],
        };
      }
      return updated;
    });
  }, [lang]);

  const startRecording = () => {
    if (!speechSupported || !recognitionRef.current) return;
    setTranscript("");
    setIsRecording(true);
    recognitionRef.current.start();
  };

  const stopRecording = () => {
    if (!recognitionRef.current) return;
    recognitionRef.current.stop();
    setIsRecording(false);
  };

  const speak = (text: string) => {
    if (!("speechSynthesis" in window)) return;
    window.speechSynthesis.cancel();
    const utterance = new SpeechSynthesisUtterance(text);
    utterance.lang = lang === "es" ? "es-ES" : "en-US";
    utterance.onstart = () => setIsSpeaking(true);
    utterance.onend = () => setIsSpeaking(false);
    utterance.onerror = () => setIsSpeaking(false);
    window.speechSynthesis.speak(utterance);
  };

  const handleSend = async (text: string) => {
    if (!text.trim() || isLoading) return;
    const userMessage: ChatMessage = {
      role: "user",
      content: text,
      timestamp: Date.now(),
    };
    setMessages((prev) => [...prev, userMessage]);
    setInput("");
    setIsLoading(true);

    try {
      const response = await fetch("/api/chat/agent", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          message: text,
          locale: lang,
          history: messages.slice(-6),
        }),
      });

      if (!response.ok) {
        throw new Error("Failed to fetch response.");
      }

      const data = (await response.json()) as ApiResponse;
      const assistantMessage: ChatMessage = {
        role: "assistant",
        content: data.response,
        timestamp: Date.now(),
      };
      setMessages((prev) => [...prev, assistantMessage]);

      if (voiceMode) {
        speak(data.response);
      }
    } catch (error) {
      const fallbackMessage: ChatMessage = {
        role: "assistant",
        content:
          lang === "es"
            ? "Hubo un problema al responder. ¿Quieres intentarlo de nuevo?"
            : "There was a problem responding. Want to try again?",
        timestamp: Date.now(),
      };
      setMessages((prev) => [...prev, fallbackMessage]);
    } finally {
      setIsLoading(false);
    }
  };

  const voiceIndicator = isRecording
    ? "🎤"
    : isSpeaking
    ? "🔊"
    : "🎤";

  return (
    <>
      {!isOpen && (
        <div className="fixed bottom-6 right-6 z-[9999] flex flex-col items-end gap-2">
          <div className="relative">
            <button
              type="button"
              onClick={() => setIsOpen(true)}
              className="relative flex h-[68px] w-[68px] items-center justify-center rounded-full bg-gradient-to-br from-[#8B5CF6] to-[#EC4899] text-white shadow-lg transition hover:scale-110 hover:shadow-[0_12px_30px_rgba(236,72,153,0.45)]"
            >
              <div className="flex items-center gap-1">
                <span className="h-3 w-1 rounded-full bg-white/80 animate-pulse" />
                <span className="h-5 w-1 rounded-full bg-white/90 animate-pulse" />
                <span className="h-4 w-1 rounded-full bg-white/80 animate-pulse" />
              </div>
            </button>
            {showTooltip && (
              <div className="absolute right-[76px] top-1/2 -translate-y-1/2 rounded-full bg-white px-3 py-1 text-xs font-semibold text-brand-purple-dark shadow-md">
                {lang === "es" ? "Prueba la voz" : "Try voice"}
              </div>
            )}
            <div className="absolute -top-6 right-2 rounded-full bg-white/20 px-2 py-1 text-[10px] font-semibold text-white backdrop-blur">
              ▶ Demo
            </div>
          </div>
        </div>
      )}

      {isOpen && (
        <div className="fixed inset-0 z-[9999] flex items-end justify-end p-4 sm:p-6">
          <div className="absolute inset-0 bg-black/50" onClick={() => setIsOpen(false)} />
          <div className="relative z-10 flex h-full w-full max-w-[440px] flex-col overflow-hidden rounded-3xl border border-white/15 bg-[#4f3a78] shadow-[0_30px_80px_rgba(0,0,0,0.45)] sm:h-[700px]">
            <div className="flex items-center justify-between bg-gradient-to-r from-[#6d4cc2] to-[#ff66b5] px-5 py-4 text-white">
              <div>
                <div className="flex items-center gap-2 text-lg font-semibold">
                  <span>SiteMente IA</span>
                  <span className="flex items-center gap-1">
                    <span className="h-2 w-1 rounded-full bg-white/80 animate-pulse" />
                    <span className="h-3 w-1 rounded-full bg-white/90 animate-pulse" />
                    <span className="h-2 w-1 rounded-full bg-white/80 animate-pulse" />
                  </span>
                </div>
                <p className="text-xs text-white/80">
                  {lang === "es" ? "El cerebro de tu web" : "Your website brain"}
                </p>
              </div>
              <div className="flex items-center gap-3 text-lg">
                <span>{voiceIndicator}</span>
                <button
                  type="button"
                  onClick={() => setLang((prev) => (prev === "es" ? "en" : "es"))}
                  className="rounded-full border border-white/30 px-2 py-1 text-xs font-semibold"
                >
                  {localeLabel}
                </button>
                <button
                  type="button"
                  onClick={() => setIsOpen(false)}
                  className="text-xl"
                >
                  ✕
                </button>
              </div>
            </div>

            <div className="flex-1 overflow-y-auto px-5 py-4">
              {messages.length === 1 && (
                <div className="mb-4 flex flex-wrap gap-2">
                  {quickActions[lang].map((action) => (
                    <button
                      key={action.label}
                      type="button"
                      onClick={() => handleSend(action.label)}
                      className="rounded-full border border-white/20 bg-white/10 px-3 py-1 text-xs text-white/90 transition hover:bg-white/20"
                    >
                      {action.icon} {action.label}
                    </button>
                  ))}
                </div>
              )}
              <div className="space-y-4">
                {messages.map((message) => (
                  <div
                    key={`${message.timestamp}-${message.role}`}
                    className={`group flex ${
                      message.role === "user" ? "justify-end" : "justify-start"
                    }`}
                  >
                    <div
                      className={`max-w-[80%] rounded-2xl px-4 py-3 text-sm shadow-md ${
                        message.role === "user"
                          ? "bg-[#c4a1ff] text-[#3b1c66]"
                          : "bg-[#6a4bb0] text-white"
                      }`}
                    >
                      <div className="flex items-center gap-2">
                        {message.role === "assistant" && (
                          <span className="flex h-6 w-6 items-center justify-center rounded-full bg-white/20 text-xs font-semibold">
                            SM
                          </span>
                        )}
                        <p>{message.content}</p>
                      </div>
                      <span className="mt-2 block text-[10px] text-white/60 opacity-0 transition group-hover:opacity-100">
                        {new Date(message.timestamp).toLocaleTimeString(
                          lang === "es" ? "es-ES" : "en-US",
                          { hour: "2-digit", minute: "2-digit" }
                        )}
                      </span>
                    </div>
                  </div>
                ))}
                {isLoading && (
                  <div className="flex items-center gap-2 text-white/70">
                    <span className="inline-flex h-2 w-2 animate-bounce rounded-full bg-white/70" />
                    <span className="inline-flex h-2 w-2 animate-bounce rounded-full bg-white/60 delay-150" />
                    <span className="inline-flex h-2 w-2 animate-bounce rounded-full bg-white/50 delay-300" />
                  </div>
                )}
                {isSpeaking && (
                  <div className="flex items-center gap-2 text-xs text-white/70">
                    <span className="flex items-center gap-1">
                      <span className="h-2 w-1 rounded-full bg-white/80 animate-pulse" />
                      <span className="h-3 w-1 rounded-full bg-white/90 animate-pulse" />
                      <span className="h-2 w-1 rounded-full bg-white/80 animate-pulse" />
                    </span>
                    {lang === "es" ? "Hablando..." : "Speaking..."}
                  </div>
                )}
                <div ref={messagesEndRef} />
              </div>
            </div>

            <div className="border-t border-white/10 bg-[#4a3572] px-5 py-4">
              {voiceMode ? (
                <div className="flex flex-col items-center gap-3">
                  {transcript && (
                    <p className="w-full rounded-xl bg-white/10 px-4 py-2 text-sm text-white/90">
                      {transcript}
                    </p>
                  )}
                  <button
                    type="button"
                    onClick={() => {
                      if (isRecording) {
                        stopRecording();
                        return;
                      }
                      if (isSpeaking) {
                        window.speechSynthesis?.cancel();
                        setIsSpeaking(false);
                        return;
                      }
                      startRecording();
                    }}
                    className={`flex h-14 w-14 items-center justify-center rounded-full text-white transition ${
                      isRecording
                        ? "bg-red-500 animate-pulse"
                        : isSpeaking
                        ? "bg-blue-500 animate-pulse"
                        : "bg-white/20 hover:bg-white/30"
                    }`}
                    disabled={!speechSupported}
                  >
                    {isRecording ? "🔴" : isSpeaking ? "🔊" : "🎤"}
                  </button>
                  <p className="text-xs text-white/80">
                    {isRecording
                      ? lang === "es"
                        ? "Escuchando..."
                        : "Listening..."
                      : isSpeaking
                      ? lang === "es"
                        ? "Hablando..."
                        : "Speaking..."
                      : lang === "es"
                      ? "Toca para hablar"
                      : "Tap to talk"}
                  </p>
                  {isSpeaking && (
                    <div className="h-1 w-full overflow-hidden rounded-full bg-white/10">
                      <div className="h-full w-1/2 animate-pulse rounded-full bg-brand-pink/80" />
                    </div>
                  )}
                  <div className="flex w-full items-center justify-between text-xs text-white/70">
                    <button
                      type="button"
                      onClick={() => setVoiceMode(false)}
                      className="flex items-center gap-1"
                    >
                      ⌨️ {lang === "es" ? "Texto" : "Text"}
                    </button>
                    <button
                      type="button"
                      onClick={() => {
                        window.speechSynthesis?.cancel();
                        setIsSpeaking(false);
                      }}
                      className="flex items-center gap-1"
                    >
                      ⏸ {lang === "es" ? "Pausar" : "Pause"}
                    </button>
                  </div>
                </div>
              ) : (
                <div className="flex items-center gap-3">
                  <input
                    value={input}
                    onChange={(event) => setInput(event.target.value)}
                    placeholder={
                      lang === "es"
                        ? "Escribe tu mensaje..."
                        : "Type your message..."
                    }
                    className="flex-1 rounded-full border border-white/20 bg-white/10 px-4 py-2 text-sm text-white placeholder:text-white/50 focus:border-white/50 focus:outline-none"
                  />
                  <button
                    type="button"
                    onClick={() => handleSend(input)}
                    className="rounded-full bg-brand-pink px-4 py-2 text-sm font-semibold text-white"
                  >
                    ➤
                  </button>
                  <button
                    type="button"
                    onClick={() => setVoiceMode(true)}
                    className="rounded-full border border-white/20 px-3 py-2 text-white/80"
                  >
                    🎤
                  </button>
                </div>
              )}
              {!speechSupported && (
                <p className="mt-2 text-center text-xs text-white/60">
                  {lang === "es"
                    ? "Tu navegador no soporta voz. Usa el modo texto."
                    : "Your browser doesn't support voice. Use text mode."}
                </p>
              )}
            </div>
          </div>
        </div>
      )}
    </>
  );
}
