"use client";

import React, { useState, useEffect } from "react";
import { Button } from "../ui/Button";
import { cn } from "../../utils/cn";

// 메시지 타입 정의
interface Message {
  id: string;
  content: string;
  sender: "user" | "ai";
  timestamp: Date;
  type?: "text" | "error" | "system";
}

// 에이전트 설정 타입
interface AgentConfig {
  name: string;
  description: string;
  greeting: string;
  personality: string;
  updatedAt: string;
}

// 답변에서 링크를 버튼으로 렌더링하는 함수
function renderAnswerWithLinks(text: string) {
  if (!text) return <span>{text}</span>;

  // 네이버 블로그 링크 패턴 감지
  const linkPattern = /(https?:\/\/blog\.naver\.com\/[^\s\n]+)/g;

  // 링크가 실제로 존재하는지 확인
  if (!/(https?:\/\/blog\.naver\.com\/[^\s\n]+)/.test(text)) {
    return <span>{text}</span>;
  }

  const parts = text.split(linkPattern);

  return (
    <span>
      {parts.map((part, index) => {
        if (part.match(linkPattern)) {
          return (
            <a
              key={index}
              href={part}
              target="_blank"
              rel="noopener noreferrer"
              className="inline-flex items-center gap-1 mx-1 px-2 py-1 bg-green-100 text-green-700 rounded-full text-xs hover:bg-green-200 transition-colors font-medium"
              title="원문 보기"
            >
              <svg
                className="w-3 h-3"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
                />
              </svg>
              🔗 원문 보기
            </a>
          );
        }
        return part;
      })}
    </span>
  );
}

// 마크다운 링크를 JSX로 변환하는 함수
function renderMessageContent(content: string) {
  const linkRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
  const parts: (string | React.ReactElement)[] = [];
  let lastIndex = 0;
  let match;

  while ((match = linkRegex.exec(content)) !== null) {
    // 링크 이전 텍스트 추가
    if (match.index > lastIndex) {
      parts.push(content.slice(lastIndex, match.index));
    }

    // 링크 추가
    parts.push(
      <a
        key={match.index}
        href={match[2]}
        target="_blank"
        rel="noopener noreferrer"
        className="text-blue-600 hover:text-blue-800 underline"
      >
        {match[1]}
      </a>
    );

    lastIndex = match.index + match[0].length;
  }

  // 남은 텍스트 추가
  if (lastIndex < content.length) {
    parts.push(content.slice(lastIndex));
  }

  return parts.length > 1 ? parts : content;
}

export interface ChatWidgetProps {
  agentConfigEndpoint?: string;
  chatEndpoint?: string;
  buttonColor?: string;
  position?: "bottom-right" | "bottom-left";
  generateFallbackResponse?: (input: string) => string;
}

export function ChatWidget({
  agentConfigEndpoint = "/api/rag/agent-config",
  chatEndpoint = "/api/rag/answer/stream",
  buttonColor = "#ef4444",
  position = "bottom-right",
  generateFallbackResponse,
}: ChatWidgetProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [inputValue, setInputValue] = useState("");
  const [agentConfig, setAgentConfig] = useState<AgentConfig>({
    name: "RAG 어시스턴트",
    description: "문서 기반 질문 답변 AI 어시스턴트",
    greeting:
      "안녕하세요! 업로드된 문서를 기반으로 질문에 답변해드립니다. 궁금한 것이 있으시면 언제든 물어보세요!",
    personality: "친근하고 도움이 되는",
    updatedAt: new Date().toISOString(),
  });
  const [messages, setMessages] = useState<Message[]>([]);

  // 에이전트 설정 로드
  const loadAgentConfig = async () => {
    try {
      const response = await fetch(agentConfigEndpoint);
      const data = await response.json();

      if (data.success) {
        setAgentConfig(data.config);

        // 초기 인사말 메시지 설정
        setMessages([
          {
            id: "1",
            content: data.config.greeting,
            sender: "ai",
            timestamp: new Date(),
            type: "text",
          },
        ]);
      }
    } catch (error) {
      console.error("에이전트 설정 로드 실패:", error);
      // 기본 인사말 사용
      setMessages([
        {
          id: "1",
          content: agentConfig.greeting,
          sender: "ai",
          timestamp: new Date(),
          type: "text",
        },
      ]);
    }
  };

  // 컴포넌트 마운트 시 에이전트 설정 로드
  useEffect(() => {
    loadAgentConfig();
  }, []);

  // 기본 폴백 응답 생성 함수
  const defaultFallbackResponse = (userInput: string): string => {
    const input = userInput.toLowerCase();

    if (input.includes("안녕") || input.includes("hello")) {
      return "안녕하세요! 현재 문서 검색에 문제가 있어 기본 응답을 드립니다. 관리자에게 문의해주세요.";
    } else if (input.includes("agentc") || input.includes("에이전트")) {
      return "AgentC는 AI 기반의 스마트 CMS 시스템입니다. 현재 문서 검색 기능에 문제가 있어 자세한 정보를 제공하지 못하고 있습니다.";
    } else {
      return `죄송합니다. 현재 문서 검색 시스템에 문제가 발생하여 "${userInput}"에 대한 정확한 답변을 드릴 수 없습니다.\n\n시스템이 복구되면 다시 시도해주세요. 또는 관리자에게 문의해주세요.`;
    }
  };

  // 메시지 전송 핸들러
  const handleSendMessage = async () => {
    if (!inputValue.trim()) return;

    const userQuery = inputValue;

    // 사용자 메시지 추가
    const userMessage: Message = {
      id: Date.now().toString(),
      content: userQuery,
      sender: "user",
      timestamp: new Date(),
      type: "text",
    };

    setMessages((prev) => [...prev, userMessage]);
    setInputValue("");

    // 로딩 메시지 추가
    const loadingMessage: Message = {
      id: (Date.now() + 1).toString(),
      content: "답변을 생성하고 있습니다...",
      sender: "ai",
      timestamp: new Date(),
      type: "system",
    };
    setMessages((prev) => [...prev, loadingMessage]);

    try {
      // RAG 스트리밍 API 호출
      const response = await fetch(chatEndpoint, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          query: userQuery,
          k: 5,
        }),
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      // 로딩 메시지 제거
      setMessages((prev) => prev.filter((msg) => msg.id !== loadingMessage.id));

      // AI 응답 메시지 생성 (빈 내용으로 시작)
      const aiResponseId = (Date.now() + 2).toString();
      const aiResponse: Message = {
        id: aiResponseId,
        content: "",
        sender: "ai",
        timestamp: new Date(),
        type: "text",
      };
      setMessages((prev) => [...prev, aiResponse]);

      // 스트리밍 처리
      const reader = response.body?.getReader();
      if (!reader) {
        throw new Error("스트림을 읽을 수 없습니다.");
      }

      const decoder = new TextDecoder();
      let buffer = "";
      let currentAnswer = "";
      let sources: any[] = [];

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split("\n");
        buffer = lines.pop() || "";

        for (const line of lines) {
          if (line.trim()) {
            try {
              const data = JSON.parse(line);

              if (data.type === "sources") {
                sources = data.content || [];
              } else if (data.type === "content") {
                currentAnswer += data.content;
                // 실시간으로 메시지 업데이트
                setMessages((prev) =>
                  prev.map((msg) =>
                    msg.id === aiResponseId
                      ? { ...msg, content: currentAnswer }
                      : msg
                  )
                );
              } else if (data.type === "error") {
                setMessages((prev) =>
                  prev.map((msg) =>
                    msg.id === aiResponseId
                      ? {
                          ...msg,
                          content: `오류: ${data.content}`,
                          type: "error",
                        }
                      : msg
                  )
                );
                break;
              }
            } catch (e) {
              // JSON 파싱 오류 무시
            }
          }
        }
      }

      // 소스 정보가 있으면 추가 (RSS가 아닌 문서만)
      const nonRSSSources = sources.filter((source: any) => !source.isRSS);
      if (nonRSSSources.length > 0) {
        const sourcesText = `\n\n📚 **참고 문서:**\n${nonRSSSources
          .map(
            (source: any) =>
              `• ${source.title} (${Math.round(source.score * 100)}%)`
          )
          .join("\n")}`;

        const sourcesMessage: Message = {
          id: (Date.now() + 3).toString(),
          content: sourcesText,
          sender: "ai",
          timestamp: new Date(),
          type: "system",
        };
        setMessages((prev) => [...prev, sourcesMessage]);
      }
    } catch (error) {
      console.error("RAG 요청 실패:", error);

      // 로딩 메시지 제거
      setMessages((prev) => prev.filter((msg) => msg.id !== loadingMessage.id));

      // 폴백 응답
      const fallbackMessage: Message = {
        id: (Date.now() + 2).toString(),
        content: generateFallbackResponse
          ? generateFallbackResponse(userQuery)
          : defaultFallbackResponse(userQuery),
        sender: "ai",
        timestamp: new Date(),
        type: "text",
      };
      setMessages((prev) => [...prev, fallbackMessage]);
    }
  };

  // 엔터키 핸들러
  const handleKeyPress = (e: React.KeyboardEvent) => {
    if (e.key === "Enter") {
      handleSendMessage();
    }
  };

  const positionClasses = {
    "bottom-right": "bottom-6 right-6",
    "bottom-left": "bottom-6 left-6",
  };

  return (
    <>
      {/* 플로팅 버튼 */}
      <div className={cn("fixed z-50", positionClasses[position])}>
        <button
          onClick={() => setIsOpen(!isOpen)}
          className="w-16 h-16 text-white rounded-full shadow-2xl transition-all duration-200 hover:scale-110 border-4 border-white flex items-center justify-center"
          style={{
            backgroundColor: buttonColor,
            boxShadow: "0 10px 25px rgba(0,0,0,0.3)",
          }}
          aria-label="채팅 열기"
        >
          {isOpen ? (
            <svg
              className="w-8 h-8"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M6 18L18 6M6 6l12 12"
              />
            </svg>
          ) : (
            <svg
              className="w-8 h-8"
              fill="none"
              stroke="currentColor"
              viewBox="0 0 24 24"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                strokeWidth={2}
                d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
              />
            </svg>
          )}
        </button>
      </div>

      {/* 채팅 UI - 반응형 */}
      {isOpen && (
        <div
          className={cn(
            "fixed z-50 bg-white flex flex-col",
            "md:w-96 md:h-96 md:rounded-2xl md:shadow-2xl md:border md:border-gray-200",
            "max-md:inset-0 max-md:w-screen max-md:h-screen max-md:rounded-none max-md:top-0 max-md:left-0 max-md:right-0 max-md:bottom-0",
            position === "bottom-right"
              ? "md:bottom-24 md:right-6"
              : "md:bottom-24 md:left-6"
          )}
        >
          {/* 헤더 */}
          <div className="flex items-center justify-between p-4 border-b border-gray-200 bg-gray-50 md:rounded-t-2xl max-md:sticky max-md:top-0 max-md:z-10">
            <div className="flex items-center gap-3">
              {/* 모바일에서만 뒤로가기 버튼 표시 */}
              <button
                onClick={() => setIsOpen(false)}
                className="md:hidden w-8 h-8 rounded-full hover:bg-gray-200 flex items-center justify-center transition-colors"
                aria-label="뒤로가기"
              >
                <svg
                  className="w-5 h-5 text-gray-600"
                  fill="none"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d="M15 19l-7-7 7-7"
                  />
                </svg>
              </button>
              <div>
                <h3 className="font-semibold text-gray-800">
                  {agentConfig.name}
                </h3>
                {agentConfig.description && (
                  <p className="text-xs text-gray-500">
                    {agentConfig.description}
                  </p>
                )}
              </div>
            </div>

            {/* 데스크톱에서만 닫기 버튼 표시 */}
            <button
              onClick={() => setIsOpen(false)}
              className="hidden md:flex w-8 h-8 rounded-full hover:bg-gray-200 items-center justify-center transition-colors"
              aria-label="닫기"
            >
              <svg
                className="w-5 h-5 text-gray-600"
                fill="none"
                stroke="currentColor"
                viewBox="0 0 24 24"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M6 18L18 6M6 6l12 12"
                />
              </svg>
            </button>
          </div>

          {/* 메시지 영역 */}
          <div className="flex-1 overflow-y-auto p-4 space-y-3 max-md:pb-20">
            {messages.map((message) => (
              <div
                key={message.id}
                className={cn(
                  "flex",
                  message.sender === "user" ? "justify-end" : "justify-start"
                )}
              >
                <div
                  className={cn(
                    "px-3 py-2 rounded-lg text-sm max-w-xs md:max-w-xs max-md:max-w-[80%]",
                    message.sender === "user"
                      ? "bg-blue-500 text-white"
                      : message.type === "system"
                      ? "bg-blue-50 text-blue-700 border border-blue-200"
                      : message.type === "error"
                      ? "bg-red-50 text-red-700 border border-red-200"
                      : "bg-gray-200 text-gray-800"
                  )}
                >
                  <div className="whitespace-pre-wrap">
                    {message.sender === "ai" && message.type === "text"
                      ? renderAnswerWithLinks(message.content)
                      : renderMessageContent(message.content)}
                  </div>
                  {message.type === "system" && (
                    <div className="text-xs text-blue-500 mt-1">
                      {message.content.includes("답변을 생성") ? "🤖" : "📚"}
                    </div>
                  )}
                </div>
              </div>
            ))}
          </div>

          {/* 입력 영역 */}
          <div className="p-4 border-t border-gray-200 bg-white max-md:fixed max-md:bottom-0 max-md:left-0 max-md:right-0 max-md:border-t-2">
            <div className="flex gap-2">
              <input
                type="text"
                value={inputValue}
                onChange={(e) => setInputValue(e.target.value)}
                onKeyPress={handleKeyPress}
                placeholder="메시지를 입력하세요..."
                className="flex-1 p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 text-base"
              />
              <Button
                onClick={handleSendMessage}
                disabled={!inputValue.trim()}
                className="px-4 py-3 min-w-[60px]"
              >
                전송
              </Button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}
