import { useCallback, useEffect, useRef, useState } from "react";
import { Bot, User, Send, Loader2, Mic, MicOff, CheckCircle2, RotateCcw, AlertTriangle, RefreshCw, ArrowRight } from "lucide-react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import type { Components } from "react-markdown";
import AudioRecorder from "./AudioRecorder";
import { getInterviewResult, type InterviewResult } from "../../../services/interviewApi";
import {
  useInterviewSession,
  type InterviewMessage,
  type InterviewMode,
} from "../../../hooks/useInterviewSession";

const markdownComponents: Components = {
  p: ({ children }) => (
    <p className="text-sm mb-1.5 last:mb-0 leading-relaxed">{children}</p>
  ),
  ul: ({ children }) => (
    <ul className="list-disc pl-4 mb-1.5 space-y-0.5 text-sm">{children}</ul>
  ),
  ol: ({ children }) => (
    <ol className="list-decimal pl-4 mb-1.5 space-y-0.5 text-sm">{children}</ol>
  ),
  li: ({ children }) => <li>{children}</li>,
  strong: ({ children }) => <strong className="font-semibold">{children}</strong>,
  em: ({ children }) => <em className="italic">{children}</em>,
};

interface InterviewPanelProps {
  roomId: string;
  userId: string;
  onComplete: () => void;
  onResultReady?: (result: InterviewResult) => void;
}

export default function InterviewPanel({ roomId, userId, onComplete, onResultReady }: InterviewPanelProps) {
  const {
    status,
    messages,
    isSending,
    isStarting,
    startError,
    interviewResult,
    isLoaded,
    startSession,
    sendTextMessage,
    connectAudio,
    disconnectAudio,
    sendAudioChunk,
    sendEndUtterance,
    switchMode,
    resetSession,
  } = useInterviewSession(roomId, userId);

  const [input, setInput] = useState("");
  const [audioMode, setAudioMode] = useState<InterviewMode>("text");
  const [audioStreamingText, setAudioStreamingText] = useState("");
  const [isAudioConnected, setIsAudioConnected] = useState(false);

  const messagesEndRef = useRef<HTMLDivElement>(null);
  const audioContextRef = useRef<AudioContext | null>(null);
  const inputRef = useRef<HTMLTextAreaElement>(null);

  // Auto-scroll to bottom
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
  }, [messages, audioStreamingText]);

  // Auto-start hanya setelah localStorage selesai dimuat dan status benar-benar idle
  useEffect(() => {
    if (isLoaded && status === "idle") {
      startSession("text");
    }
  }, [isLoaded, status]); // eslint-disable-line react-hooks/exhaustive-deps

  // Notify parent when result is ready (from hook or re-fetched)
  useEffect(() => {
    if (status === "completed" && interviewResult) {
      onResultReady?.(interviewResult);
    } else if (status === "completed" && !interviewResult) {
      getInterviewResult(roomId)
        .then((r) => onResultReady?.(r))
        .catch(() => {});
    }
  }, [status, interviewResult]); // eslint-disable-line react-hooks/exhaustive-deps

  // Setup audio WebSocket when audio mode is active
  useEffect(() => {
    if (audioMode !== "audio" || status !== "active") return;
    if (isAudioConnected) return;

    setIsAudioConnected(true);
    connectAudio(
      (token) => setAudioStreamingText((prev) => prev + token),
      (fullText) => {
        setAudioStreamingText("");
        // The hook handles adding the message internally, but for audio we add it here
        // since audio messages arrive differently
        void fullText; // handled via useInterviewSession internal state if needed
      },
      async (audioBuf) => {
        // Play TTS audio
        try {
          if (!audioContextRef.current || audioContextRef.current.state === "closed") {
            audioContextRef.current = new AudioContext();
          }
          const ctx = audioContextRef.current;
          const decoded = await ctx.decodeAudioData(audioBuf.slice(0));
          const source = ctx.createBufferSource();
          source.buffer = decoded;
          source.connect(ctx.destination);
          source.start();
        } catch {
          // ignore playback errors
        }
      },
      () => {
        setIsAudioConnected(false);
        onComplete();
      }
    );

    return () => {
      disconnectAudio();
      setIsAudioConnected(false);
    };
  }, [audioMode, status]); // eslint-disable-line react-hooks/exhaustive-deps

  const handleSendText = useCallback(async () => {
    const text = input.trim();
    if (!text || isSending || status !== "active") return;
    setInput("");
    await sendTextMessage(text);
    inputRef.current?.focus();
  }, [input, isSending, status, sendTextMessage]);

  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      handleSendText();
    }
  };

  const handleModeToggle = () => {
    const next: InterviewMode = audioMode === "text" ? "audio" : "text";
    setAudioMode(next);
    switchMode(next);
    setIsAudioConnected(false);
    setAudioStreamingText("");
  };

  const handleRestart = () => {
    setAudioMode("text");
    setIsAudioConnected(false);
    setAudioStreamingText("");
    resetSession();
    startSession("text");
  };

  // Loading state saat memanggil API untuk membuat sesi
  if (isStarting) {
    return (
      <div className="flex-1 flex flex-col items-center justify-center gap-3 text-slate-500">
        <Loader2 className="w-6 h-6 animate-spin text-emerald-600" />
        <p className="text-sm">Memulai sesi interview…</p>
      </div>
    );
  }

  // Error state — backend tidak bisa dijangkau
  if (startError && status === "idle") {
    return (
      <div className="flex-1 flex flex-col items-center justify-center gap-4 px-6">
        <div className="flex flex-col items-center gap-2 text-center">
          <AlertTriangle className="w-8 h-8 text-amber-400" />
          <p className="text-sm font-medium text-slate-700">Tidak dapat terhubung ke server interview</p>
          <p className="text-xs text-slate-400 max-w-xs">
            Pastikan backend interview berjalan di <code className="bg-slate-100 px-1 py-0.5 rounded text-xs">localhost:8080</code>
          </p>
        </div>
        <div className="flex items-center gap-2">
          <button
            onClick={() => startSession("text")}
            className="flex items-center gap-1.5 px-3 py-2 bg-emerald-600 hover:bg-emerald-700 text-white text-xs rounded-lg transition"
          >
            <RefreshCw className="w-3.5 h-3.5" />
            Coba Lagi
          </button>
          <button
            onClick={onComplete}
            className="flex items-center gap-1.5 px-3 py-2 bg-slate-100 hover:bg-slate-200 text-slate-600 text-xs rounded-lg transition"
          >
            Lanjut ke Analytics
            <ArrowRight className="w-3.5 h-3.5" />
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="flex-1 flex flex-col min-h-0">
      {/* Mode toggle bar */}
      <div className="flex items-center justify-between px-4 py-2 border-b border-slate-100 bg-white/60 backdrop-blur-sm">
        <p className="text-xs text-slate-500">
          {status === "completed"
            ? "Interview selesai — lihat hasil di bawah"
            : "Jawab pertanyaan untuk membantu analisis data Anda"}
        </p>
        <div className="flex items-center gap-2">
          {status === "completed" && (
            <button
              onClick={handleRestart}
              className="flex items-center gap-1 text-xs text-slate-400 hover:text-slate-600 transition"
            >
              <RotateCcw className="w-3 h-3" />
              Mulai ulang
            </button>
          )}
          {status === "active" && (
            <button
              onClick={handleModeToggle}
              title={audioMode === "text" ? "Beralih ke mode audio" : "Beralih ke mode teks"}
              className={`flex items-center gap-1.5 text-xs px-2.5 py-1 rounded-full border transition-all duration-200 ${
                audioMode === "audio"
                  ? "bg-emerald-50 border-emerald-200 text-emerald-700"
                  : "bg-slate-50 border-slate-200 text-slate-500 hover:border-slate-300"
              }`}
            >
              {audioMode === "audio" ? (
                <Mic className="w-3 h-3" />
              ) : (
                <MicOff className="w-3 h-3" />
              )}
              <span>{audioMode === "audio" ? "Audio" : "Teks"}</span>
            </button>
          )}
        </div>
      </div>

      {/* Messages */}
      <div className="flex-1 overflow-y-auto px-4 py-4 space-y-3">
        {messages.map((msg) => (
          <MessageBubble key={msg.id} message={msg} />
        ))}

        {/* Live audio streaming text */}
        {audioStreamingText && (
          <div className="flex gap-2.5 max-w-[85%]">
            <div className="w-7 h-7 rounded-full bg-emerald-100 flex items-center justify-center flex-shrink-0 mt-0.5">
              <Bot className="w-4 h-4 text-emerald-600" />
            </div>
            <div className="bg-white border border-slate-200 rounded-2xl rounded-tl-sm px-3.5 py-2.5 shadow-sm">
              <p className="text-sm text-slate-700 leading-relaxed">
                {audioStreamingText}
                <span className="inline-block w-1 h-3.5 bg-emerald-500 ml-0.5 animate-pulse rounded-sm" />
              </p>
            </div>
          </div>
        )}

        {/* Completed state */}
        {status === "completed" && (
          <div className="flex justify-center py-4">
            <div className="flex items-center gap-2 text-emerald-600 bg-emerald-50 border border-emerald-200 rounded-full px-4 py-2 text-sm">
              <CheckCircle2 className="w-4 h-4" />
              <span>Interview selesai!</span>
            </div>
          </div>
        )}

        <div ref={messagesEndRef} />
      </div>

      {/* CTA setelah interview selesai */}
      {status === "completed" && (
        <div className="border-t border-slate-100 px-4 py-3 flex justify-end">
          <button
            onClick={onComplete}
            className="flex items-center gap-2 px-4 py-2 bg-emerald-600 hover:bg-emerald-700 text-white text-sm rounded-xl transition"
          >
            Lanjut ke Analytics
            <ArrowRight className="w-4 h-4" />
          </button>
        </div>
      )}

      {/* Input area */}
      {status === "active" && (
        <div className="border-t border-slate-200 bg-white/80 backdrop-blur-sm p-3">
          {audioMode === "audio" ? (
            <div className="flex items-center justify-center gap-3 py-2">
              <p className="text-sm text-slate-500">
                Tahan tombol mikrofon lalu bicara
              </p>
              <AudioRecorder
                onChunk={sendAudioChunk}
                onEndUtterance={sendEndUtterance}
                disabled={isSending}
              />
            </div>
          ) : (
            <div className="flex items-end gap-2">
              <textarea
                ref={inputRef}
                value={input}
                onChange={(e) => setInput(e.target.value)}
                onKeyDown={handleKeyPress}
                placeholder="Ketik jawaban Anda…"
                rows={1}
                disabled={isSending}
                className="flex-1 resize-none bg-slate-50 border border-slate-200 rounded-xl px-3.5 py-2.5 text-sm text-slate-800 placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-emerald-400 focus:border-transparent transition max-h-32 disabled:opacity-60"
                style={{ minHeight: "42px" }}
                onInput={(e) => {
                  const el = e.currentTarget;
                  el.style.height = "auto";
                  el.style.height = `${Math.min(el.scrollHeight, 128)}px`;
                }}
              />
              <button
                onClick={handleSendText}
                disabled={!input.trim() || isSending}
                className="w-9 h-9 rounded-full bg-emerald-600 hover:bg-emerald-700 disabled:bg-slate-200 disabled:cursor-not-allowed text-white flex items-center justify-center flex-shrink-0 transition-all duration-200 hover:scale-105 disabled:scale-100"
              >
                {isSending ? (
                  <Loader2 className="w-4 h-4 animate-spin" />
                ) : (
                  <Send className="w-4 h-4" />
                )}
              </button>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function MessageBubble({ message }: { message: InterviewMessage }) {
  const isUser = message.role === "user";

  if (isUser) {
    return (
      <div className="flex gap-2.5 max-w-[85%] ml-auto flex-row-reverse">
        <div className="w-7 h-7 rounded-full bg-blue-600 flex items-center justify-center flex-shrink-0 mt-0.5">
          <User className="w-4 h-4 text-white" />
        </div>
        <div className="bg-blue-600 text-white rounded-2xl rounded-tr-sm px-3.5 py-2.5 shadow-sm">
          <p className="text-sm leading-relaxed whitespace-pre-wrap">{message.content}</p>
        </div>
      </div>
    );
  }

  return (
    <div className="flex gap-2.5 max-w-[85%]">
      <div className="w-7 h-7 rounded-full bg-emerald-100 flex items-center justify-center flex-shrink-0 mt-0.5">
        <Bot className="w-4 h-4 text-emerald-600" />
      </div>
      <div className="bg-white border border-slate-200 rounded-2xl rounded-tl-sm px-3.5 py-2.5 shadow-sm">
        {message.isStreaming && !message.content ? (
          <div className="flex gap-1 py-1">
            <span className="w-1.5 h-1.5 bg-emerald-400 rounded-full animate-bounce [animation-delay:0ms]" />
            <span className="w-1.5 h-1.5 bg-emerald-400 rounded-full animate-bounce [animation-delay:150ms]" />
            <span className="w-1.5 h-1.5 bg-emerald-400 rounded-full animate-bounce [animation-delay:300ms]" />
          </div>
        ) : (
          <div className="text-slate-700">
            <ReactMarkdown
              remarkPlugins={[remarkGfm]}
              components={markdownComponents}
            >
              {message.content}
            </ReactMarkdown>
            {message.isStreaming && (
              <span className="inline-block w-1 h-3.5 bg-emerald-500 ml-0.5 animate-pulse rounded-sm" />
            )}
          </div>
        )}
      </div>
    </div>
  );
}
