
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 } 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;
}

const ChatInterface: React.FC<ChatInterfaceProps> = ({
  files,
  settings,
  models,
  groups,
  selectedGroups,
  onGroupSelectionChange,
  onOpenGroupSelection,
  selectedFiles,
  onClearFileSelection,
  onMobileUploadClick,
  currentHistoryId,
  historyMessages,
  onHistoryMessagesLoaded,
  onPreviewSource,
  onOpenFile,
  onHistoryIdCreated
}) => {
  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 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]);

    const authToken = localStorage.getItem('authToken');
    if (!authToken) {
      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 = '';

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

      const stream = chatService.streamChat(
        userText,
        history,
        authToken,
        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しきい値を渡す
      );

      for await (const chunk of stream) {
        if (chunk.type === 'content') {
          botContent += chunk.data;
          setMessages(prev =>
            prev.map(msg =>
              msg.id === botMessageId
                ? { ...msg, text: botContent }
                : msg
            )
          );
        } else if (chunk.type === 'sources') {
          // Attach sources to the current bot message
          setMessages(prev =>
            prev.map(msg =>
              msg.id === botMessageId
                ? { ...msg, sources: chunk.data }
                : msg
            )
          );
        } else if (chunk.type === 'historyId') {
          onHistoryIdCreated?.(chunk.data);
        } else if (chunk.type === '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);
      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-slate-50 relative overflow-hidden">
      <div className="flex-1 overflow-y-auto p-4 md:p-6 space-y-6 scrollbar-hide">
        {messages.map((msg) => (
          <ChatMessage
            key={msg.id}
            message={msg}
            onPreviewSource={onPreviewSource}
            onOpenFile={onOpenFile}
          />
        ))}

        {isLoading && (
          <div className="flex justify-start animate-in fade-in duration-300">
            <div className="flex flex-row gap-3">
              <div className="w-8 h-8 rounded-full bg-white border border-slate-200 flex items-center justify-center shadow-sm">
                <Loader2 className="w-4 h-4 text-purple-600 animate-spin" />
              </div>
              <div className="bg-white border border-slate-100 px-4 py-3 rounded-2xl rounded-tl-none shadow-sm flex items-center">
                <span className="text-sm text-slate-500">{t('analyzing')}</span>
              </div>
            </div>
          </div>
        )}
        <div ref={messagesEndRef} />


      </div>



      <div className="p-4 bg-gradient-to-t from-slate-50 via-slate-50 to-transparent shrink-0">
        <div className="max-w-3xl mx-auto">
          {((selectedFiles && selectedFiles.length > 0) || true) && (
            <div className="mb-2 flex flex-wrap gap-2 animate-in slide-in-from-bottom-2">
              {/* Group Selection Button */}
              <button
                type="button"
                onClick={onOpenGroupSelection}
                className={`flex items-center gap-2 px-3 py-1 rounded-full text-xs font-medium transition-colors border ${selectedGroups.length > 0
                  ? 'bg-slate-100 text-slate-700 border-slate-300 hover:bg-slate-200'
                  : 'bg-slate-50 text-slate-600 border-slate-200 hover:bg-slate-100'
                  }`}
                title={t('selectKnowledgeGroup')}
              >
                <Database size={12} />
                <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 bg-blue-100 text-blue-700 px-2 py-1 rounded-full text-xs font-medium border border-blue-200">
                  <span className="truncate max-w-[150px]">{file.name}</span>
                  <button
                    onClick={onClearFileSelection}
                    className="hover:bg-blue-200 rounded-full p-0.5 transition-colors"
                  >
                    <X size={12} />
                  </button>
                </div>
              ))}
            </div>
          )}

          <div className="bg-white rounded-xl shadow-lg border border-slate-200 flex items-end p-2 transition-shadow focus-within:shadow-xl focus-within:border-blue-300">


            <button
              onClick={onMobileUploadClick}
              className="md:hidden p-3 text-slate-400 hover:text-blue-600 hover:bg-blue-50 rounded-lg 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-40 min-h-[50px] bg-transparent border-none focus:ring-0 text-slate-700 placeholder:text-slate-400 resize-none py-3 px-3"
              rows={1}
              disabled={files.length === 0 && messages.length < 2 && false} // Disable logic might need review, relaxed for now
            />
            <button
              onClick={handleSend}
              disabled={!input.trim() || isLoading}
              className={`p - 3 rounded - lg mb - 0.5 ml - 2 transition - all ${input.trim() && !isLoading
                ? 'bg-blue-600 text-white hover:bg-blue-700 shadow-md transform hover:scale-105'
                : 'bg-slate-100 text-slate-400 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 mt-2">
            {t('aiDisclaimer')}
          </p>
        </div>
      </div>
    </div>
  );
};

export default ChatInterface;
