/**
 * Chat Panel Component
 * Main chat interface with markdown rendering and message actions
 */

import { useRef, useEffect, useState, type KeyboardEvent } from 'react';
import Markdown from 'react-markdown';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
// KaTeX CSS is loaded from CDN in index.html to reduce bundle size
import { 
  Send, 
  Square, 
  Trash2, 
  MessageSquare, 
  User, 
  Bot,
  RefreshCw,
  Pencil,
  Check,
  X,
  Loader2,
  Brain,
  ChevronDown,
  AlertCircle
} from 'lucide-react';
import { useChat, useI18n } from '@/contexts';
import type { ChatMessage } from '@/types';
import styles from './ChatPanel.module.css';

/**
 * Custom hook for elapsed time tracking with capture.
 * Starts counting when isActive becomes true, stops and captures final value when it becomes false.
 * Returns: { liveMs, finalMs, displayMs } where displayMs shows live during active, final after.
 */
function useElapsedTimer(isActive: boolean): { liveMs: number; finalMs: number; displayMs: number } {
  const startTimeRef = useRef<number | null>(null);
  const [liveMs, setLiveMs] = useState(0);
  const [finalMs, setFinalMs] = useState(0);
  const wasActiveRef = useRef(false);

  // Handle activation/deactivation
  useEffect(() => {
    if (isActive && !wasActiveRef.current) {
      // Just became active - start timer
      startTimeRef.current = Date.now();
      setLiveMs(0);
    } else if (!isActive && wasActiveRef.current) {
      // Just became inactive - capture final time
      if (startTimeRef.current !== null) {
        const elapsed = Date.now() - startTimeRef.current;
        setFinalMs(elapsed);
        setLiveMs(elapsed);
        startTimeRef.current = null;
      }
    }
    wasActiveRef.current = isActive;
  }, [isActive]);

  // Tick interval while active
  useEffect(() => {
    if (!isActive || startTimeRef.current === null) return;
    
    const interval = setInterval(() => {
      if (startTimeRef.current !== null) {
        setLiveMs(Date.now() - startTimeRef.current);
      }
    }, 100); // Update every 100ms for smooth display
    
    return () => clearInterval(interval);
  }, [isActive]);

  // displayMs: live while active, final after
  const displayMs = isActive ? liveMs : finalMs;

  return { liveMs, finalMs, displayMs };
}

export function ChatPanel() {
  const { t } = useI18n();
  const { 
    messages, 
    isStreaming, 
    currentStatus,
    sendMessage, 
    clearMessages, 
    stopGeneration,
    regenerateFrom,
    editMessage 
  } = useChat();
  const [input, setInput] = useState('');
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const textareaRef = useRef<HTMLTextAreaElement>(null);

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

  // Auto-resize textarea
  useEffect(() => {
    const textarea = textareaRef.current;
    if (textarea) {
      textarea.style.height = 'auto';
      textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`;
    }
  }, [input]);

  const handleSend = async () => {
    if (!input.trim() || isStreaming) return;
    const content = input;
    setInput('');
    await sendMessage(content);
  };

  const handleKeyDown = (e: KeyboardEvent<HTMLTextAreaElement>) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  };

  return (
    <div className={styles.chatPanel}>
      {/* Message List */}
      <div className={styles.messageList}>
        {messages.length === 0 ? (
          <div className={styles.emptyState}>
            <MessageSquare className={styles.emptyIcon} />
            <h2 className={styles.emptyTitle}>{t.chat.startConversation}</h2>
            <p className={styles.emptyDescription}>
              {t.chat.startDescription}
            </p>
          </div>
        ) : (
          messages.map((message, index) => (
            <Message 
              key={message.id} 
              message={message}
              showStatus={isStreaming && index === messages.length - 1 && message.role === 'assistant'}
              currentStatus={currentStatus}
              onEdit={(newContent) => editMessage(message.id, newContent)}
              onRegenerate={() => regenerateFrom(message.id)}
              disabled={isStreaming}
            />
          ))
        )}
        <div ref={messagesEndRef} />
      </div>

      {/* Input Area */}
      <div className={styles.inputArea}>
        <div className={styles.inputWrapper}>
          <textarea
            ref={textareaRef}
            className={styles.textarea}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder={t.chat.placeholder}
            rows={1}
            disabled={isStreaming}
          />
          <div className={styles.actionButtons}>
            {messages.length > 0 && (
              <button
                className={styles.clearButton}
                onClick={clearMessages}
                title={t.chat.clearChat}
                disabled={isStreaming}
              >
                <Trash2 size={20} />
              </button>
            )}
            {isStreaming ? (
              <button
                className={`${styles.sendButton} ${styles.stopButton}`}
                onClick={stopGeneration}
                title={t.chat.stopGenerating}
              >
                <Square size={20} />
              </button>
            ) : (
              <button
                className={styles.sendButton}
                onClick={handleSend}
                disabled={!input.trim()}
                title={t.chat.sendMessage}
              >
                <Send size={20} />
              </button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

// Message Component
function Message({ 
  message, 
  showStatus,
  currentStatus,
  onEdit,
  onRegenerate,
  disabled
}: { 
  message: ChatMessage;
  showStatus?: boolean;
  currentStatus?: string;
  onEdit: (content: string) => void;
  onRegenerate: () => void;
  disabled: boolean;
}) {
  const { t } = useI18n();
  const [isEditing, setIsEditing] = useState(false);
  const [editContent, setEditContent] = useState(message.content);
  // Capture both dimensions to match edit area to original message box
  const [editDimensions, setEditDimensions] = useState<{ width?: number; height?: number }>({});
  const editTextareaRef = useRef<HTMLTextAreaElement>(null);
  const messageContentRef = useRef<HTMLDivElement>(null);
  const messageTextRef = useRef<HTMLDivElement>(null);
  const isUser = message.role === 'user';
  
  // Thinking section state - auto-expand while thinking, auto-collapse when done
  const hasThinking = Boolean(message.thinkingContent);
  const [isThinkingExpanded, setIsThinkingExpanded] = useState(message.isThinking ?? false);
  
  // Timer hooks - track total streaming duration and thinking duration
  // The hook now returns displayMs which shows live during active, final after
  const isCurrentlyStreaming = message.isStreaming === true;
  const streamingTimer = useElapsedTimer(isCurrentlyStreaming);
  
  const isActivelyThinking = message.isThinking === true;
  const thinkingTimer = useElapsedTimer(isActivelyThinking);
  
  // Convert to seconds for display (minimum 1s if any time recorded)
  const totalSeconds = streamingTimer.displayMs > 0 ? Math.max(1, Math.floor(streamingTimer.displayMs / 1000)) : 0;
  const thinkingSeconds = thinkingTimer.displayMs > 0 ? Math.max(1, Math.floor(thinkingTimer.displayMs / 1000)) : 0;
  
  // Auto-collapse thinking when thinking phase ends
  useEffect(() => {
    if (message.isThinking) {
      setIsThinkingExpanded(true);
    } else if (hasThinking && !message.isStreaming) {
      // Thinking done and streaming finished - collapse
      setIsThinkingExpanded(false);
    }
  }, [message.isThinking, message.isStreaming, hasThinking]);

  // Start editing: capture dimensions and sync content
  const startEditing = () => {
    const width = messageContentRef.current?.offsetWidth;
    const height = messageTextRef.current?.offsetHeight;
    setEditDimensions({ width, height });
    setEditContent(message.content);
    setIsEditing(true);
  };

  // Auto-resize textarea to fit content
  useEffect(() => {
    if (isEditing && editTextareaRef.current) {
      const textarea = editTextareaRef.current;
      textarea.style.height = 'auto';
      textarea.style.height = `${textarea.scrollHeight}px`;
    }
  }, [isEditing, editContent]);
  
  const handleSaveEdit = () => {
    if (editContent.trim()) {
      onEdit(editContent.trim());
      setIsEditing(false);
    }
  };

  const handleCancelEdit = () => {
    setEditContent(message.content);
    setIsEditing(false);
  };
  
  // Format seconds as MM:SS or just SS if under 1 minute
  const formatTime = (seconds: number): string => {
    if (seconds < 60) return `${seconds}s`;
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
  };

  return (
    <div className={`${styles.message} ${isUser ? styles.user : styles.assistant}`}>
      <div className={`${styles.avatar} ${isUser ? styles.user : styles.assistant}`}>
        {message.isStreaming ? (
          <Loader2 size={16} className={styles.spinningIcon} />
        ) : isUser ? (
          <User size={16} />
        ) : (
          <Bot size={16} />
        )}
      </div>
      <div className={styles.messageWrapper}>
        {/* Collapsible thinking section for AI messages - ABOVE the message content */}
        {!isUser && hasThinking && (
          <div className={`${styles.thinkingSection} ${isThinkingExpanded ? styles.expanded : styles.collapsed} ${message.error ? styles.thinkingError : ''}`}>
            <button 
              className={styles.thinkingHeader}
              onClick={() => setIsThinkingExpanded(!isThinkingExpanded)}
              type="button"
            >
              <div className={styles.thinkingHeaderLeft}>
                {message.error ? (
                  <AlertCircle size={14} className={styles.errorIcon} />
                ) : (
                  <Brain size={14} className={message.isThinking ? styles.spinningIcon : ''} />
                )}
                <span>{message.error ? t.chat.thinkingInterrupted : message.isThinking ? t.chat.thinking : t.chat.thinkingProcess}</span>
              </div>
              <div className={styles.thinkingHeaderRight}>
                {!message.error && (
                  <span className={styles.thinkingTimer}>{formatTime(thinkingSeconds)}</span>
                )}
                <ChevronDown 
                  size={14} 
                  className={`${styles.thinkingChevron} ${isThinkingExpanded ? styles.rotated : ''}`} 
                />
              </div>
            </button>
            {isThinkingExpanded && (
              <div className={styles.thinkingContent}>
                <Markdown
                  remarkPlugins={[remarkMath]}
                  rehypePlugins={[rehypeKatex]}
                >
                  {message.thinkingContent || ''}
                </Markdown>
              </div>
            )}
          </div>
        )}
        
        <div ref={messageContentRef} className={styles.messageContent}>
          {isEditing ? (
            <div className={styles.editArea} style={editDimensions.width ? { width: editDimensions.width } : undefined}>
              <textarea
                ref={editTextareaRef}
                className={styles.editTextarea}
                value={editContent}
                onChange={(e) => setEditContent(e.target.value)}
                autoFocus
              />
              <div className={styles.editActions}>
                <button 
                  className={styles.editActionButton}
                  onClick={handleSaveEdit}
                  title={t.common.save}
                >
                  <Check size={14} /> {t.common.save}
                </button>
                <button 
                  className={`${styles.editActionButton} ${styles.cancel}`}
                  onClick={handleCancelEdit}
                  title={t.common.cancel}
                >
                  <X size={14} /> {t.common.cancel}
                </button>
              </div>
            </div>
          ) : (
            <>
              <div ref={messageTextRef} className={styles.messageText}>
                {isUser ? (
                  // User messages: plain text
                  message.content
                ) : (
                  // AI messages: markdown with LaTeX support
                  <Markdown
                    remarkPlugins={[remarkMath]}
                    rehypePlugins={[rehypeKatex]}
                    components={{
                      // Better code block rendering
                      code({ className, children, ...props }) {
                        const match = /language-(\w+)/.exec(className || '');
                        return match ? (
                          <pre className={styles.codeBlock}>
                            <code className={className} {...props}>
                              {children}
                            </code>
                          </pre>
                        ) : (
                          <code className={styles.inlineCode} {...props}>
                            {children}
                          </code>
                        );
                      },
                    }}
                  >
                    {message.content}
                  </Markdown>
                )}
                {message.isStreaming && <span className={styles.streamingCursor} />}
              </div>
              {message.error && (
                <div className={styles.messageError}>{message.error}</div>
              )}
            </>
          )}
        </div>
        {/* Status display with total timer during streaming */}
        {showStatus && currentStatus && (
          <div className={styles.statusBar}>
            <Loader2 size={12} className={styles.spinningIcon} />
            <span>{currentStatus}</span>
            {/* Show total timer (thinking + response) during streaming */}
            <span className={styles.responseTimer}>{formatTime(totalSeconds)}</span>
          </div>
        )}

        {/* Total time badge - always visible for AI messages with time */}
        {!isUser && !message.isStreaming && totalSeconds > 0 && (
          <div className={styles.totalTimeBadge}>
            <span>{t.chat.totalTime} {formatTime(totalSeconds)}</span>
          </div>
        )}

        {/* Action buttons - both message types have edit and regen */}
        {!isEditing && !message.isStreaming && (
          <div className={styles.messageActions}>
            <button 
              className={styles.actionButton}
              onClick={startEditing}
              disabled={disabled}
              title={t.chat.editMessage}
            >
              <Pencil size={14} />
            </button>
            <button 
              className={styles.actionButton}
              onClick={onRegenerate}
              disabled={disabled}
              title={isUser ? t.chat.resend : t.chat.regenerate}
            >
              <RefreshCw size={14} />
            </button>
          </div>
        )}
      </div>
    </div>
  );
}
