/**
 * StudioChat - Context-aware AI chat for Studio
 * 
 * Uses the existing useChat hook to communicate with Claude via WebSocket.
 * Injects model files and context documents into the conversation.
 */

import React, { useRef, useEffect, useState, useMemo } from 'react';
import { Send, Loader2, Sparkles, FileText, Wifi, WifiOff, Bot, User, File, AlertCircle } from 'lucide-react';
import { useChat } from '../../hooks/useChat';
import { useSpecStore, useSpec } from '../../hooks/useSpecStore';
import { MarkdownRenderer } from '../MarkdownRenderer';
import { ToolCallCard } from '../chat/ToolCallCard';

interface StudioChatProps {
  draftId: string;
  contextFiles: string[];
  contextContent: string;
  modelFiles: string[];
  onSpecUpdated: () => void;
}

export const StudioChat: React.FC<StudioChatProps> = ({
  draftId,
  contextFiles,
  contextContent,
  modelFiles,
  onSpecUpdated,
}) => {
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLTextAreaElement>(null);
  const [input, setInput] = useState('');
  const [hasInjectedContext, setHasInjectedContext] = useState(false);
  
  // Get spec store for canvas updates
  const spec = useSpec();
  const { reloadSpec, setSpecFromWebSocket } = useSpecStore();
  
  // Build canvas state with full context for Claude
  const canvasState = useMemo(() => ({
    nodes: [],
    edges: [],
    studyName: draftId,
    studyPath: `_inbox/${draftId}`,
    // Include file info for Claude context
    modelFiles,
    contextFiles,
    contextContent: contextContent.substring(0, 50000), // Limit context size
  }), [draftId, modelFiles, contextFiles, contextContent]);
  
  // Use the chat hook with WebSocket
  // Power mode gives Claude write permissions to modify the spec
  const {
    messages,
    isThinking,
    error,
    isConnected,
    sendMessage,
    updateCanvasState,
  } = useChat({
    studyId: draftId,
    mode: 'power',  // Power mode = --dangerously-skip-permissions = can write files
    useWebSocket: true,
    canvasState,
    onError: (err) => console.error('[StudioChat] Error:', err),
    onSpecUpdated: (newSpec) => {
      // Claude modified the spec - update the store directly
      console.log('[StudioChat] Spec updated by Claude');
      setSpecFromWebSocket(newSpec, draftId);
      onSpecUpdated();
    },
    onCanvasModification: (modification) => {
      // Claude wants to modify canvas - reload the spec
      console.log('[StudioChat] Canvas modification:', modification);
      reloadSpec();
      onSpecUpdated();
    },
  });
  
  // Update canvas state when context changes
  useEffect(() => {
    updateCanvasState(canvasState);
  }, [canvasState, updateCanvasState]);
  
  // Scroll to bottom when messages change
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages]);
  
  // Auto-focus input
  useEffect(() => {
    inputRef.current?.focus();
  }, []);
  
  // Build context summary for display
  const contextSummary = useMemo(() => {
    const parts: string[] = [];
    if (modelFiles.length > 0) {
      parts.push(`${modelFiles.length} model file${modelFiles.length > 1 ? 's' : ''}`);
    }
    if (contextFiles.length > 0) {
      parts.push(`${contextFiles.length} context doc${contextFiles.length > 1 ? 's' : ''}`);
    }
    if (contextContent) {
      parts.push(`${contextContent.length.toLocaleString()} chars context`);
    }
    return parts.join(', ');
  }, [modelFiles, contextFiles, contextContent]);
  
  const handleSend = () => {
    if (!input.trim() || isThinking) return;
    
    let messageToSend = input.trim();
    
    // On first message, inject full context so Claude has everything it needs
    if (!hasInjectedContext && (modelFiles.length > 0 || contextContent)) {
      const contextParts: string[] = [];
      
      // Add model files info
      if (modelFiles.length > 0) {
        contextParts.push(`**Model Files Uploaded:**\n${modelFiles.map(f => `- ${f}`).join('\n')}`);
      }
      
      // Add context document content (full text)
      if (contextContent) {
        contextParts.push(`**Context Documents Content:**\n\`\`\`\n${contextContent.substring(0, 30000)}\n\`\`\``);
      }
      
      // Add current spec state
      if (spec) {
        const dvCount = spec.design_variables?.length || 0;
        const objCount = spec.objectives?.length || 0;
        const extCount = spec.extractors?.length || 0;
        if (dvCount > 0 || objCount > 0 || extCount > 0) {
          contextParts.push(`**Current Configuration:** ${dvCount} design variables, ${objCount} objectives, ${extCount} extractors`);
        }
      }
      
      if (contextParts.length > 0) {
        messageToSend = `${contextParts.join('\n\n')}\n\n---\n\n**User Request:** ${messageToSend}`;
      }
      
      setHasInjectedContext(true);
    }
    
    sendMessage(messageToSend);
    setInput('');
  };
  
  const handleKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      handleSend();
    }
  };
  
  // Welcome message for empty state
  const showWelcome = messages.length === 0;
  
  // Check if we have any context
  const hasContext = modelFiles.length > 0 || contextContent.length > 0;
  
  return (
    <div className="h-full flex flex-col">
      {/* Header */}
      <div className="p-3 border-b border-dark-700 flex-shrink-0">
        <div className="flex items-center justify-between mb-2">
          <div className="flex items-center gap-2">
            <Sparkles className="w-5 h-5 text-primary-400" />
            <span className="font-medium text-white">Studio Assistant</span>
          </div>
          <span className={`flex items-center gap-1 text-xs px-2 py-0.5 rounded ${
            isConnected 
              ? 'text-green-400 bg-green-400/10' 
              : 'text-red-400 bg-red-400/10'
          }`}>
            {isConnected ? <Wifi className="w-3 h-3" /> : <WifiOff className="w-3 h-3" />}
            {isConnected ? 'Connected' : 'Disconnected'}
          </span>
        </div>
        
        {/* Context indicator */}
        {contextSummary && (
          <div className="flex items-center gap-2 text-xs">
            <div className="flex items-center gap-1 text-amber-400 bg-amber-400/10 px-2 py-1 rounded">
              <FileText className="w-3 h-3" />
              <span>{contextSummary}</span>
            </div>
            {hasContext && !hasInjectedContext && (
              <span className="text-dark-500">Will be sent with first message</span>
            )}
            {hasInjectedContext && (
              <span className="text-green-500">Context sent</span>
            )}
          </div>
        )}
      </div>
      
      {/* Messages */}
      <div className="flex-1 overflow-y-auto p-3 space-y-4">
        {/* Welcome message with context awareness */}
        {showWelcome && (
          <div className="flex gap-3">
            <div className="flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center bg-primary-500/20 text-primary-400">
              <Bot className="w-4 h-4" />
            </div>
            <div className="flex-1 bg-dark-700 rounded-lg px-4 py-3 text-sm text-dark-100">
              <MarkdownRenderer content={hasContext 
                ? `I can see you've uploaded files. Here's what I have access to:

${modelFiles.length > 0 ? `**Model Files:** ${modelFiles.join(', ')}` : ''}
${contextContent ? `\n**Context Document:** ${contextContent.substring(0, 200)}...` : ''}

Tell me what you want to optimize and I'll help you configure the study!`
                : `Welcome to Atomizer Studio! I'm here to help you configure your optimization study.

**What I can do:**
- Read your uploaded context documents
- Help set up design variables, objectives, and constraints
- Create extractors for physics outputs
- Suggest optimization strategies

Upload your model files and any requirements documents, then tell me what you want to optimize!`} />
            </div>
          </div>
        )}
        
        {/* File context display (only if we have files but no messages yet) */}
        {showWelcome && modelFiles.length > 0 && (
          <div className="bg-dark-800/50 rounded-lg p-3 border border-dark-700">
            <p className="text-xs text-dark-400 mb-2 font-medium">Loaded Files:</p>
            <div className="flex flex-wrap gap-2">
              {modelFiles.map((file, idx) => (
                <span key={idx} className="flex items-center gap-1 text-xs bg-blue-500/10 text-blue-400 px-2 py-1 rounded">
                  <File className="w-3 h-3" />
                  {file}
                </span>
              ))}
              {contextFiles.map((file, idx) => (
                <span key={idx} className="flex items-center gap-1 text-xs bg-amber-500/10 text-amber-400 px-2 py-1 rounded">
                  <FileText className="w-3 h-3" />
                  {file}
                </span>
              ))}
            </div>
          </div>
        )}
        
        {/* Chat messages */}
        {messages.map((msg) => {
          const isAssistant = msg.role === 'assistant';
          const isSystem = msg.role === 'system';
          
          // System messages
          if (isSystem) {
            return (
              <div key={msg.id} className="flex justify-center my-2">
                <div className="px-3 py-1 bg-dark-700/50 rounded-full text-xs text-dark-400 border border-dark-600">
                  {msg.content}
                </div>
              </div>
            );
          }
          
          return (
            <div
              key={msg.id}
              className={`flex gap-3 ${isAssistant ? '' : 'flex-row-reverse'}`}
            >
              {/* Avatar */}
              <div
                className={`flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center ${
                  isAssistant
                    ? 'bg-primary-500/20 text-primary-400'
                    : 'bg-dark-600 text-dark-300'
                }`}
              >
                {isAssistant ? <Bot className="w-4 h-4" /> : <User className="w-4 h-4" />}
              </div>
              
              {/* Message content */}
              <div
                className={`flex-1 max-w-[85%] rounded-lg px-4 py-3 text-sm ${
                  isAssistant
                    ? 'bg-dark-700 text-dark-100'
                    : 'bg-primary-500 text-white ml-auto'
                }`}
              >
                {isAssistant ? (
                  <>
                    {msg.content && <MarkdownRenderer content={msg.content} />}
                    {msg.isStreaming && !msg.content && (
                      <span className="text-dark-400">Thinking...</span>
                    )}
                    {/* Tool calls */}
                    {msg.toolCalls && msg.toolCalls.length > 0 && (
                      <div className="mt-3 space-y-2">
                        {msg.toolCalls.map((tool, idx) => (
                          <ToolCallCard key={idx} toolCall={tool} />
                        ))}
                      </div>
                    )}
                  </>
                ) : (
                  <span className="whitespace-pre-wrap">{msg.content}</span>
                )}
              </div>
            </div>
          );
        })}
        
        {/* Thinking indicator */}
        {isThinking && messages.length > 0 && !messages[messages.length - 1]?.isStreaming && (
          <div className="flex gap-3">
            <div className="flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center bg-primary-500/20 text-primary-400">
              <Bot className="w-4 h-4" />
            </div>
            <div className="bg-dark-700 rounded-lg px-4 py-3 flex items-center gap-2">
              <Loader2 className="w-4 h-4 text-primary-400 animate-spin" />
              <span className="text-sm text-dark-300">Thinking...</span>
            </div>
          </div>
        )}
        
        {/* Error display */}
        {error && (
          <div className="flex gap-3">
            <div className="flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center bg-red-500/20 text-red-400">
              <AlertCircle className="w-4 h-4" />
            </div>
            <div className="flex-1 px-4 py-3 bg-red-500/10 rounded-lg text-sm text-red-400 border border-red-500/30">
              {error}
            </div>
          </div>
        )}
        
        <div ref={messagesEndRef} />
      </div>
      
      {/* Input */}
      <div className="p-3 border-t border-dark-700 flex-shrink-0">
        <div className="flex gap-2">
          <textarea
            ref={inputRef}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder={isConnected ? "Ask about your optimization..." : "Connecting..."}
            disabled={!isConnected}
            rows={1}
            className="flex-1 bg-dark-700 border border-dark-600 rounded-lg px-3 py-2 text-sm text-white placeholder-dark-400 resize-none focus:outline-none focus:border-primary-400 disabled:opacity-50"
          />
          <button
            onClick={handleSend}
            disabled={!input.trim() || isThinking || !isConnected}
            className="p-2 bg-primary-500 text-white rounded-lg hover:bg-primary-400 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
          >
            {isThinking ? (
              <Loader2 className="w-5 h-5 animate-spin" />
            ) : (
              <Send className="w-5 h-5" />
            )}
          </button>
        </div>
        {!isConnected && (
          <p className="text-xs text-dark-500 mt-1">
            Waiting for connection to Claude...
          </p>
        )}
      </div>
    </div>
  );
};

export default StudioChat;
