"use client";

import React, { useState, useCallback, useEffect, useMemo } from "react";
import FloatingChatButton from "./floating-chat-button";
import ChatDock, { Message } from "./chat-dock";
import { useSuggestedQuestions } from "./suggested-questions";
import {
  ChatbotAPI,
  ChatbotAPIError,
  withRetry,
} from "../../../../services/chatbot-api";
import { useDebounce } from "../../../../hooks/usePerformance";
import { I18nProvider, useI18n } from "./i18n-context";
import { useTheme, ThemeName, applyTheme } from "./theme-config";

interface ChatbotWidgetProps {
  apiBaseUrl?: string;
  apiKey?: string;
  position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
  buttonSize?: "sm" | "md" | "lg";
  buttonColor?: string;
  title?: string;
  placeholder?: string;
  enableSuggestedQuestions?: boolean;
  enableTypingIndicator?: boolean;
  enableRetry?: boolean;
  maxRetries?: number;
  className?: string;
  disabled?: boolean;
  onError?: (error: ChatbotAPIError) => void;
  onMessageSent?: (message: string) => void;
  onMessageReceived?: (message: Message) => void;
  // Theme and i18n props
  theme?: ThemeName;
  language?: string;
  enableLanguageSelector?: boolean;
  enableThemeToggle?: boolean;
}

// Internal widget component that uses contexts
function ChatbotWidgetInternal({
  apiBaseUrl,
  apiKey,
  position = "bottom-right",
  buttonSize = "md",
  buttonColor = "#3B82F6",
  title,
  placeholder,
  enableSuggestedQuestions = true,
  enableTypingIndicator = true,
  enableRetry = true,
  maxRetries = 3,
  className = "",
  disabled = false,
  onError,
  onMessageSent,
  onMessageReceived,
  enableLanguageSelector = false,
  enableThemeToggle = false,
}: Omit<ChatbotWidgetProps, "theme" | "language">) {
  // Use i18n context
  const { t, currentLanguage, isRTL } = useI18n();

  // Use default values from translations if not provided
  const displayTitle = title || t("chatbot");
  const displayPlaceholder = placeholder || t("placeholder");
  const [isOpen, setIsOpen] = useState(false);
  const [messages, setMessages] = useState<Message[]>([]);
  const [isTyping, setIsTyping] = useState(false);
  const [unreadCount, setUnreadCount] = useState(0);
  const [connectionStatus, setConnectionStatus] = useState<
    "connected" | "connecting" | "error"
  >("connected");
  const [lastError, setLastError] = useState<string | null>(null);

  const {
    context: suggestedQuestionsContext,
    updateContext: updateSuggestedQuestionsContext,
    resetQuestions,
  } = useSuggestedQuestions();

  // Debounce typing indicator
  const debouncedTyping = useDebounce(isTyping, 300);

  // Initialize ChatbotAPI
  const chatbotAPI = useMemo(() => {
    return new ChatbotAPI(apiBaseUrl, apiKey);
  }, [apiBaseUrl, apiKey]);

  // Handle health check on mount
  useEffect(() => {
    const checkConnection = async () => {
      try {
        setConnectionStatus("connecting");
        await chatbotAPI.healthCheck();
        setConnectionStatus("connected");
      } catch (error) {
        console.warn("챗봇 연결 확인 실패:", error);
        setConnectionStatus("error");
      }
    };

    checkConnection();
  }, [chatbotAPI]);

  // Generate unique message ID
  const generateMessageId = useCallback(() => {
    return `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }, []);

  // Handle opening/closing chat
  const handleToggleChat = useCallback(() => {
    setIsOpen((prev) => {
      const newIsOpen = !prev;
      if (newIsOpen) {
        setUnreadCount(0);
        resetQuestions();
      }
      return newIsOpen;
    });
  }, [resetQuestions]);

  const handleCloseChat = useCallback(() => {
    setIsOpen(false);
  }, []);

  // Add message to chat
  const addMessage = useCallback(
    (message: Omit<Message, "id">) => {
      const newMessage: Message = {
        ...message,
        id: generateMessageId(),
      };

      setMessages((prev) => [...prev, newMessage]);

      // Update unread count if chat is closed
      if (!isOpen && message.sender === "ai") {
        setUnreadCount((prev) => prev + 1);
      }

      // Callback for message received
      if (message.sender === "ai" && onMessageReceived) {
        onMessageReceived(newMessage);
      }

      return newMessage;
    },
    [isOpen, generateMessageId, onMessageReceived]
  );

  // Handle sending message
  const handleSendMessage = useCallback(
    async (content: string) => {
      if (!content.trim() || disabled || isTyping) return;

      try {
        // Clear any previous errors
        setLastError(null);

        // Add user message
        const userMessage = addMessage({
          content,
          sender: "user",
          timestamp: new Date(),
          type: "text",
        });

        // Callback for message sent
        if (onMessageSent) {
          onMessageSent(content);
        }

        // Update suggested questions context based on content
        if (
          content.toLowerCase().includes("가격") ||
          content.toLowerCase().includes("요금")
        ) {
          updateSuggestedQuestionsContext("pricing");
        } else if (
          content.toLowerCase().includes("문제") ||
          content.toLowerCase().includes("오류")
        ) {
          updateSuggestedQuestionsContext("error");
        }

        // Show typing indicator
        setIsTyping(true);

        // Send message to API with retry
        const operation = () =>
          chatbotAPI.sendMessage({
            message: content,
            context: {
              messageHistory: messages.slice(-5), // Send last 5 messages for context
            },
          });

        const response = enableRetry
          ? await withRetry(operation, maxRetries, 1000)
          : await operation();

        // Add AI response
        addMessage({
          content: response.content,
          sender: "ai",
          timestamp: response.timestamp,
          type: "text",
        });
      } catch (error) {
        console.error("메시지 전송 실패:", error);

        const apiError =
          error instanceof ChatbotAPIError
            ? error
            : new ChatbotAPIError(
                "메시지 전송에 실패했습니다",
                0,
                "SEND_ERROR"
              );

        setLastError(apiError.message);

        // Add error message to chat
        addMessage({
          content: `${t("errorGeneric")}: ${apiError.message}`,
          sender: "ai",
          timestamp: new Date(),
          type: "error",
        });

        // Call error callback
        if (onError) {
          onError(apiError);
        }
      } finally {
        setIsTyping(false);
      }
    },
    [
      disabled,
      isTyping,
      addMessage,
      onMessageSent,
      messages,
      updateSuggestedQuestionsContext,
      chatbotAPI,
      enableRetry,
      maxRetries,
      onError,
    ]
  );

  // Handle retry last message
  const handleRetry = useCallback(() => {
    if (messages.length >= 2) {
      const lastUserMessage = messages
        .slice()
        .reverse()
        .find((msg) => msg.sender === "user");

      if (lastUserMessage) {
        handleSendMessage(lastUserMessage.content);
      }
    }
  }, [messages, handleSendMessage]);

  // Determine if there are any error messages
  const hasErrors = useMemo(() => {
    return messages.some((msg) => msg.type === "error") || lastError !== null;
  }, [messages, lastError]);

  // Connection status indicator
  const getConnectionStatusColor = () => {
    switch (connectionStatus) {
      case "connected":
        return "#10B981"; // green
      case "connecting":
        return "#F59E0B"; // yellow
      case "error":
        return "#EF4444"; // red
      default:
        return "#6B7280"; // gray
    }
  };

  return (
    <div className={`chatbot-widget ${className}`}>
      {/* Floating Chat Button */}
      <FloatingChatButton
        onClick={handleToggleChat}
        isOpen={isOpen}
        unreadCount={unreadCount}
        position={position}
        size={buttonSize}
        color={hasErrors ? "#EF4444" : getConnectionStatusColor()}
        disabled={disabled}
        ariaLabel={
          disabled ? t("offline") : isOpen ? t("closeChat") : t("openChat")
        }
      />

      {/* Chat Dock */}
      <ChatDock
        isOpen={isOpen}
        onClose={handleCloseChat}
        onSendMessage={handleSendMessage}
        messages={messages}
        isTyping={enableTypingIndicator && debouncedTyping}
        title={displayTitle}
        placeholder={disabled ? t("offline") : displayPlaceholder}
        position={
          position === "top-right" || position === "top-left"
            ? "bottom-right"
            : position
        }
        disabled={disabled || isTyping}
        showSuggestedQuestions={enableSuggestedQuestions}
        suggestedQuestionsContext={suggestedQuestionsContext}
      />

      {/* Error Recovery */}
      {hasErrors && enableRetry && (
        <div className="fixed bottom-4 left-1/2 transform -translate-x-1/2 z-50">
          <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg shadow-lg flex items-center space-x-3">
            <span className="text-sm">{t("errorNetwork")}</span>
            <button
              onClick={handleRetry}
              className="bg-red-500 hover:bg-red-600 text-white px-3 py-1 rounded text-sm transition-colors"
            >
              {t("retry")}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

// Hook for managing chatbot widget state
export function useChatbotWidget() {
  const [isOpen, setIsOpen] = useState(false);
  const [messages, setMessages] = useState<Message[]>([]);
  const [unreadCount, setUnreadCount] = useState(0);

  const openChat = useCallback(() => {
    setIsOpen(true);
    setUnreadCount(0);
  }, []);

  const closeChat = useCallback(() => {
    setIsOpen(false);
  }, []);

  const clearMessages = useCallback(() => {
    setMessages([]);
    setUnreadCount(0);
  }, []);

  const addMessage = useCallback(
    (message: Omit<Message, "id">) => {
      const newMessage: Message = {
        ...message,
        id: `msg_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
      };

      setMessages((prev) => [...prev, newMessage]);

      if (!isOpen && message.sender === "ai") {
        setUnreadCount((prev) => prev + 1);
      }

      return newMessage;
    },
    [isOpen]
  );

  return {
    isOpen,
    messages,
    unreadCount,
    openChat,
    closeChat,
    clearMessages,
    addMessage,
  };
}

// Main ChatbotWidget component with providers
export function ChatbotWidget({
  theme = "default",
  language,
  ...props
}: ChatbotWidgetProps) {
  const { theme: currentTheme } = useTheme(theme);

  // Apply theme on mount and when theme changes
  React.useEffect(() => {
    applyTheme(currentTheme);
  }, [currentTheme]);

  return (
    <I18nProvider
      defaultLanguage={language as "ko" | "en" | "ja" | "ar" | undefined}
      enableAutoDetect={!language}
    >
      <div data-chatbot className="chatbot-root">
        <ChatbotWidgetInternal {...props} />
      </div>
    </I18nProvider>
  );
}

export default ChatbotWidget;
