
import React, { useState, useRef, useEffect } from 'react';
import { Send, Loader2, Paperclip, X, Search, Database } from 'lucide-react';
import { useLanguage } from '../contexts/LanguageContext';
import {
  AppSettings,
  KnowledgeFile,
  ModelConfig,
  Message,
  Role,
  KnowledgeGroup
} from '../types';
import ChatMessage from './ChatMessage'; // Assuming ChatMessage is a default export based on original code
import SearchResultsPanel from './SearchResultsPanel';
import { chatService, ChatMessage as ChatMsg, ChatSource, ChatStreamChunk, HistoryData, StatusData } from '../services/chatService';
import { generateUUID } from '../utils/uuid';

interface ChatInterfaceProps {
  files: KnowledgeFile[];
  settings: AppSettings;
  models: ModelConfig[];
  groups: KnowledgeGroup[];
  selectedGroups: string[];
  onGroupSelectionChange?: (groupIds: string[]) => void;
  onOpenGroupSelection?: () => void; // New prop
  selectedFiles?: string[];
  onClearFileSelection?: () => void;
  onMobileUploadClick: () => void;
  currentHistoryId?: string;
  historyMessages?: any[] | null;
  onHistoryMessagesLoaded?: () => void;
  onPreviewSource?: (source: ChatSource) => void;
  onOpenFile?: (source: ChatSource) => void;
  onHistoryIdCreated?: (historyId: string) => void;
  authToken?: string; // Add authToken prop
}

const ChatInterface: React.FC<ChatInterfaceProps> = ({
  files,
  settings,
  models,
  groups,
  selectedGroups,
  onGroupSelectionChange,
  onOpenGroupSelection,
  selectedFiles,
  onClearFileSelection,
  onMobileUploadClick,
  currentHistoryId,
  historyMessages,
  onHistoryMessagesLoaded,
  onPreviewSource,
  onOpenFile,
  onHistoryIdCreated,
  authToken: propAuthToken // Use prop
}) => {
  const { t, language } = useLanguage();
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [sources, setSources] = useState<ChatSource[]>([]);
  const [showSources, setShowSources] = useState(false);
  const [thinking, setThinking] = useState<string>('');
  const [showThinking, setShowThinking] = useState(false);
  const [statusMessage, setStatusMessage] = useState<string>('');
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLTextAreaElement>(null);
  const lastSubmitTime = useRef<number>(0);

  // Debug logging
  // console.log('ChatInterface Render:', {
  //   selectedFilesCount: selectedFiles?.length,
  //   totalFilesCount: files.length,
  //   selectedFiles: selectedFiles,
  //   matchedFiles: files.filter(f => selectedFiles?.includes(f.id)).map(f => f.name)
  // });

  // 履歴メッセージの読み込みを処理
  // 履歴メッセージの読み込みを処理
  useEffect(() => {
    if (historyMessages && historyMessages.length > 0) {
      const convertedMessages: Message[] = historyMessages.map(msg => ({
        id: msg.id,
        role: msg.role === 'user' ? Role.USER : Role.MODEL,
        text: msg.content,
        timestamp: new Date(msg.createdAt).getTime(),
        sources: msg.sources // Attach sources to message
      }));

      setMessages(convertedMessages);

      // 履歴メッセージが読み込まれたことを親コンポーネントに通知
      onHistoryMessagesLoaded?.();
    }
  }, [historyMessages, onHistoryMessagesLoaded]);

  useEffect(() => {
    const welcomeText = t('welcomeMessage');
    setMessages((prevMessages) => {
      if (prevMessages.length === 0) {
        return [
          {
            id: 'welcome',
            role: Role.MODEL,
            text: welcomeText,
            timestamp: Date.now(),
          },
        ];
      }
      const hasWelcome = prevMessages.some(m => m.id === 'welcome');
      if (hasWelcome) {
        return prevMessages.map(m =>
          m.id === 'welcome'
            ? { ...m, text: welcomeText }
            : m
        );
      }
      return prevMessages;
    });
  }, [t]);

  const scrollToBottom = () => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  };

  useEffect(() => {
    scrollToBottom();
  }, [messages]);

  const handleSend = async () => {
    if (!input.trim() || isLoading) return;

    // デバウンス機構：500ms以内の重複送信を防止
    const now = Date.now();
    if (now - lastSubmitTime.current < 500) {
      console.log('Preventing duplicate submission');
      return;
    }
    lastSubmitTime.current = now;

    const userText = input.trim();

    // 入力欄を即座にクリアして高さをリセットし、重複送信を防止
    setInput('');
    if (inputRef.current) {
      inputRef.current.style.height = 'auto';
      inputRef.current.blur(); // フォーカスを外す
    }

    // Resolve Model Config
    const selectedModel = models.find(m => m.id === settings.selectedLLMId && m.type === 'llm');

    if (!selectedModel) {
      const errorMsg: Message = {
        id: generateUUID(),
        role: Role.MODEL,
        text: `${t('errorNoModel')} - LLM ID: ${settings.selectedLLMId}, Models: ${models.length} `,
        timestamp: Date.now(),
        isError: true,
      };
      setMessages(prev => [...prev, errorMsg]);
      return;
    }

    const newMessage: Message = {
      id: generateUUID(),
      role: Role.USER,
      text: userText,
      timestamp: Date.now(),
    };

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

    // Use token from props if available, fallback to localStorage (with correct key)
    const finalToken = propAuthToken || localStorage.getItem('kb_api_key') || localStorage.getItem('authToken');
    
    if (!finalToken) {
      const errorMsg: Message = {
        id: generateUUID(),
        role: Role.MODEL,
        text: t('needLogin'),
        timestamp: Date.now(),
        isError: true,
      };
      setMessages(prev => [...prev, errorMsg]);
      setIsLoading(false);
      return;
    }

    try {
      const history: ChatMsg[] = messages
        .filter(m => m.id !== 'welcome')
        .map(m => ({
          role: m.role === Role.USER ? 'user' : 'assistant',
          content: m.text,
        }));

      const botMessageId = generateUUID();
      let botContent = '';
      let botThinking = '';

      // Reset thinking state for new message
      setThinking('');
      setShowThinking(false);
      setStatusMessage('');

      // 初期ボットメッセージを追加
      const botMessage: Message = {
        id: botMessageId,
        role: Role.MODEL,
        text: '',
        timestamp: Date.now(),
      };
      setMessages(prev => [...prev, botMessage]);

      const stream = chatService.streamChat(
        userText,
        history,
        finalToken,
        language,
        settings.selectedEmbeddingId,
        settings.selectedLLMId, // Pass selected LLM ID
        selectedGroups.length > 0 ? selectedGroups : undefined, // グループフィルタを渡す
        selectedFiles?.length > 0 ? selectedFiles : undefined, // ファイルフィルタを渡す
        currentHistoryId, // 履歴IDを渡す
        settings.enableRerank, // Rerankスイッチを渡す
        settings.selectedRerankId, // RerankモデルIDを渡す
        settings.temperature, // 温度パラメータを渡す
        settings.maxTokens, // 最大トークン数を渡す
        settings.topK, // Top-Kパラメータを渡す
        settings.similarityThreshold, // 類似度しきい値を渡す
        settings.rerankSimilarityThreshold, // Rerankしきい値を渡す
        settings.enableQueryExpansion, // クエリ拡張を渡す
        settings.enableHyDE // HyDEを渡す
      );

      for await (const chunk of stream) {
        switch (chunk.type) {
          case 'content':
            botContent += chunk.data;
            setMessages(prev =>
              prev.map(msg =>
                msg.id === botMessageId
                  ? { ...msg, text: botContent }
                  : msg
              )
            );
            break;

          case 'thinking':
            botThinking += chunk.data;
            setThinking(botThinking);
            setShowThinking(true);
            break;

          case 'sources':
            // Attach sources to the current bot message
            setMessages(prev =>
              prev.map(msg =>
                msg.id === botMessageId
                  ? { ...msg, sources: chunk.data }
                  : msg
              )
            );
            break;

          case 'historyId':
            onHistoryIdCreated?.(chunk.data);
            break;

          case 'status':
            const statusData = chunk.data as StatusData;
            if (statusData.stage === 'searching' || statusData.stage === 'generating') {
              setStatusMessage(statusData.message);
            }
            // Debug messages can be logged or shown in dev mode
            if (statusData.stage === 'debug') {
              console.log('[Chat Debug]', statusData.message);
            }
            break;

          case 'error':
            setMessages(prev =>
              prev.map(msg =>
                msg.id === botMessageId
                  ? { ...msg, text: t('errorMessage').replace('$1', chunk.data), isError: true }
                  : msg
              )
            );
            break;
        }
      }
    } catch (error: any) {
      console.error('Chat error:', error);
      let errorText = t('errorGeneric');

      if (error.message === "API_KEY_MISSING") errorText = t('apiError');
      else if (error.message.includes("OpenAI API Error")) errorText = `OpenAI Error: ${error.message} `;
      else if (error.message === "GEMINI_API_ERROR") errorText = t('geminiError');
      else if (error.message) errorText = `Error: ${error.message} `;

      const errorMessage: Message = {
        id: generateUUID(),
        role: Role.MODEL,
        text: errorText,
        timestamp: Date.now(),
        isError: true,
      };
      setMessages((prev) => [...prev, errorMessage]);
    } finally {
      setIsLoading(false);
      setStatusMessage('');
      setShowThinking(false);
      lastSubmitTime.current = 0;
    }
  };

  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      if (!isLoading && input.trim()) {
        handleSend();
      }
    }
  };

  const handleInputResize = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
    setInput(e.target.value);
    e.target.style.height = 'auto';
    e.target.style.height = `${Math.min(e.target.scrollHeight, 200)} px`;
  };

  return (
    <div className="flex flex-col h-full bg-transparent relative overflow-hidden">
      <div className="flex-1 overflow-y-auto px-4 md:px-8 pt-6 pb-32 space-y-8 scrollbar-hide">
        {messages.map((msg) => (
          <ChatMessage
            key={msg.id}
            message={msg}
            onPreviewSource={onPreviewSource}
            onOpenFile={onOpenFile}
          />
        ))}

        {/* Thinking Section */}
        {showThinking && thinking && (
          <div className="flex justify-start animate-in fade-in slide-in-from-left-2 duration-300">
            <div className="flex flex-row gap-4 items-start translate-x-1">
              <div className="w-9 h-9 rounded-xl bg-purple-100 backdrop-blur-sm border border-purple-200/50 flex items-center justify-center shadow-sm">
                <Loader2 className="w-4 h-4 text-purple-600 animate-spin" />
              </div>
              <div className="bg-purple-50/80 backdrop-blur-md border border-purple-200/40 px-5 py-3.5 rounded-2xl rounded-tl-none shadow-sm max-w-2xl">
                <div className="flex items-center gap-2 mb-2">
                  <span className="text-xs font-semibold text-purple-600 uppercase tracking-wide">深度思考</span>
                </div>
                <div className="text-sm text-purple-800 whitespace-pre-wrap">{thinking}</div>
              </div>
            </div>
          </div>
        )}

        {/* Status Message */}
        {statusMessage && (
          <div className="flex justify-start animate-in fade-in slide-in-from-left-2 duration-300">
            <div className="flex flex-row gap-4 items-start translate-x-1">
              <div className="w-9 h-9 rounded-xl bg-white/80 backdrop-blur-sm border border-slate-200/50 flex items-center justify-center shadow-sm">
                <Loader2 className="w-4 h-4 text-indigo-600 animate-spin" />
              </div>
              <div className="bg-white/80 backdrop-blur-md border border-white/40 px-5 py-3.5 rounded-2xl rounded-tl-none shadow-sm flex items-center">
                <div className="flex items-center gap-2">
                  <div className="flex gap-1">
                    <span className="w-1.5 h-1.5 bg-indigo-400 rounded-full animate-bounce [animation-delay:-0.3s]"></span>
                    <span className="w-1.5 h-1.5 bg-indigo-400 rounded-full animate-bounce [animation-delay:-0.15s]"></span>
                    <span className="w-1.5 h-1.5 bg-indigo-400 rounded-full animate-bounce"></span>
                  </div>
                  <span className="text-sm font-medium text-slate-500 ml-2 tracking-wide">{statusMessage}</span>
                </div>
              </div>
            </div>
          </div>
        )}

        {isLoading && !statusMessage && !showThinking && (
          <div className="flex justify-start animate-in fade-in slide-in-from-left-2 duration-300">
            <div className="flex flex-row gap-4 items-start translate-x-1">
              <div className="w-9 h-9 rounded-xl bg-white/80 backdrop-blur-sm border border-slate-200/50 flex items-center justify-center shadow-sm">
                <Loader2 className="w-4 h-4 text-indigo-600 animate-spin" />
              </div>
              <div className="bg-white/80 backdrop-blur-md border border-white/40 px-5 py-3.5 rounded-2xl rounded-tl-none shadow-sm flex items-center">
                <div className="flex items-center gap-2">
                  <div className="flex gap-1">
                    <span className="w-1.5 h-1.5 bg-indigo-400 rounded-full animate-bounce [animation-delay:-0.3s]"></span>
                    <span className="w-1.5 h-1.5 bg-indigo-400 rounded-full animate-bounce [animation-delay:-0.15s]"></span>
                    <span className="w-1.5 h-1.5 bg-indigo-400 rounded-full animate-bounce"></span>
                  </div>
                  <span className="text-sm font-medium text-slate-500 ml-2 tracking-wide uppercase text-[10px]">{t('analyzing')}</span>
                </div>
              </div>
            </div>
          </div>
        )}
        <div ref={messagesEndRef} />


      </div>



      <div className="absolute bottom-6 left-0 right-0 px-4 md:px-8 pointer-events-none">
        <div className="max-w-4xl mx-auto pointer-events-auto">
          {((selectedFiles && selectedFiles.length > 0) || true) && (
            <div className="mb-3 flex flex-wrap gap-2 animate-in slide-in-from-bottom-2 duration-300">
              {/* Group Selection Button */}
              <button
                type="button"
                onClick={onOpenGroupSelection}
                className={`flex items-center gap-2 px-3.5 py-1.5 rounded-full text-xs font-semibold transition-all border shadow-sm ${selectedGroups.length > 0
                  ? 'bg-blue-600 text-white border-blue-500 hover:bg-blue-700'
                  : 'bg-white/90 backdrop-blur-md text-slate-600 border-slate-200/60 hover:bg-white'
                  }`}
                title={t('selectKnowledgeGroup')}
              >
                <Database size={13} className={selectedGroups.length > 0 ? "text-blue-100" : "text-blue-500"} />
                <span className="truncate max-w-[150px]">
                  {selectedGroups.length === 0
                    ? t('allKnowledgeGroups')
                    : selectedGroups.length <= 1
                      ? (groups.find(g => g.id === selectedGroups[0])?.name || t('unknownGroup'))
                      : t('selectedGroupsCount').replace('$1', selectedGroups.length.toString())}
                </span>
              </button>

              {files.filter(f => selectedFiles?.includes(f.id)).map(file => (
                <div key={file.id} className="flex items-center gap-1.5 bg-indigo-50 text-indigo-700 px-3 py-1.5 rounded-full text-xs font-semibold border border-indigo-100 shadow-sm animate-in zoom-in-95">
                  <span className="truncate max-w-[150px]">{file.title || file.name}</span>
                  <button
                    onClick={onClearFileSelection}
                    className="hover:bg-indigo-200/50 rounded-full p-0.5 transition-colors"
                  >
                    <X size={12} />
                  </button>
                </div>
              ))}
            </div>
          )}

          <div className="bg-white rounded-2xl border border-slate-200 shadow-sm flex items-end p-2.5 transition-all duration-300 focus-within:ring-2 focus-within:ring-blue-500/20 focus-within:border-blue-400 group/input">
            <button
              onClick={onMobileUploadClick}
              className="md:hidden p-3 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-xl transition-colors"
            >
              <Paperclip className="w-5 h-5" />
            </button>

            <textarea
              ref={inputRef}
              value={input}
              onChange={handleInputResize}
              onKeyDown={handleKeyDown}
              placeholder={files.length > 0 ? t('placeholderWithFiles') : t('placeholderEmpty')}
              className="flex-1 max-h-[250px] min-h-[48px] bg-transparent border-none focus:ring-0 text-slate-800 placeholder:text-slate-400/80 resize-none py-3 px-4 text-[15px] leading-relaxed"
              rows={1}
              disabled={files.length === 0 && messages.length < 2 && false}
            />
            <button
              onClick={handleSend}
              disabled={!input.trim() || isLoading}
              className={`p-3 rounded-xl mb-0.5 ml-2 transition-all duration-300 ${input.trim() && !isLoading
                ? 'bg-gradient-to-br from-blue-600 to-indigo-600 text-white hover:shadow-lg hover:shadow-blue-500/30 transform hover:-translate-y-0.5 active:translate-y-0 active:scale-95'
                : 'bg-slate-100 text-slate-300 cursor-not-allowed'
                } `}
              type="button"
            >
              {isLoading ? (
                <Loader2 className="w-5 h-5 animate-spin" />
              ) : (
                <Send className="w-5 h-5" />
              )}
            </button>
          </div>
          <p className="text-center text-[10px] text-slate-400/80 mt-3 font-medium tracking-tight uppercase">
            {t('aiDisclaimer')}
          </p>
        </div>
      </div>
    </div>
  );
};

export default ChatInterface;
