import { useState, useEffect, useRef } from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { socketClient } from '../lib/socket';
import { chatSessionApi, projectApi, type ChatSession, type ChatTurn, type Project } from '../lib/api';

interface ChatMessage {
  id: string;
  role: 'user' | 'assistant' | 'system';
  content: string;
  thinking?: string;
  toolCalls?: Array<{
    callId: string;
    name: string;
    parameters?: string;
    response?: string;
  }>;
  timestamp: Date;
}

export default function ChatSessionView() {
  const { projectId, sessionId } = useParams<{ projectId: string; sessionId: string }>();
  const navigate = useNavigate();
  const socket = socketClient.socket;
  
  const [project, setProject] = useState<Project | null>(null);
  const [session, setSession] = useState<ChatSession | null>(null);
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [promptInput, setPromptInput] = useState('');
  const [isProcessing, setIsProcessing] = useState(false);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLTextAreaElement>(null);

  useEffect(() => {
    loadSessionData();
  }, [projectId, sessionId]);

  useEffect(() => {
    setupSocketListeners();
    return () => cleanupSocketListeners();
  }, [sessionId]);

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

  const loadSessionData = async () => {
    try {
      // Load project
      if (projectId) {
        const projectData = await projectApi.get(projectId);
        setProject(projectData);
      }

      // Load chat session
      if (sessionId) {
        const sessionData = await chatSessionApi.get(sessionId);
        setSession(sessionData);

        // Load existing turns
        const turns = await chatSessionApi.getTurns(sessionId);
        const chatMessages: ChatMessage[] = turns.map((turn: ChatTurn) => ({
          id: turn._id,
          role: 'user',
          content: turn.prompts.user,
          timestamp: new Date(turn.createdAt),
        }));

        // Add assistant responses
        turns.forEach((turn: ChatTurn) => {
          if (turn.thinking || turn.response || turn.toolCalls?.length) {
            chatMessages.push({
              id: `${turn._id}-response`,
              role: 'assistant',
              content: turn.response || '',
              thinking: turn.thinking,
              toolCalls: turn.toolCalls,
              timestamp: new Date(turn.createdAt),
            });
          }
        });

        setMessages(chatMessages);
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load session');
    } finally {
      setLoading(false);
    }
  };

  const setupSocketListeners = () => {
    if (!socket) return;

    socket.on('thinking', handleThinking);
    socket.on('response', handleResponse);
    socket.on('toolCall', handleToolCall);
    socket.on('workOrderComplete', handleWorkOrderComplete);
  };

  const cleanupSocketListeners = () => {
    if (!socket) return;

    socket.off('thinking', handleThinking);
    socket.off('response', handleResponse);
    socket.off('toolCall', handleToolCall);
    socket.off('workOrderComplete', handleWorkOrderComplete);
  };

  const handleThinking = (content: string) => {
    setMessages(prev => {
      const lastMessage = prev[prev.length - 1];
      if (lastMessage && lastMessage.role === 'assistant') {
        return [
          ...prev.slice(0, -1),
          {
            ...lastMessage,
            thinking: (lastMessage.thinking || '') + content,
          },
        ];
      }
      return prev;
    });
  };

  const handleResponse = (content: string) => {
    setMessages(prev => {
      const lastMessage = prev[prev.length - 1];
      if (lastMessage && lastMessage.role === 'assistant') {
        return [
          ...prev.slice(0, -1),
          {
            ...lastMessage,
            content: lastMessage.content + content,
          },
        ];
      }
      return prev;
    });
  };

  const handleToolCall = (callId: string, name: string, params: string, response: string) => {
    setMessages(prev => {
      const lastMessage = prev[prev.length - 1];
      if (lastMessage && lastMessage.role === 'assistant') {
        const toolCalls = lastMessage.toolCalls || [];
        toolCalls.push({ callId, name, parameters: params, response });
        return [
          ...prev.slice(0, -1),
          {
            ...lastMessage,
            toolCalls,
          },
        ];
      }
      return prev;
    });
  };

  const handleWorkOrderComplete = (turnId: string, success: boolean, message?: string) => {
    setIsProcessing(false);
    if (!success) {
      setError(message || 'Work order failed');
    }
  };

  const handleSubmitPrompt = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!promptInput.trim() || isProcessing || !socket) return;

    const userMessage: ChatMessage = {
      id: `temp-${Date.now()}`,
      role: 'user',
      content: promptInput.trim(),
      timestamp: new Date(),
    };

    setMessages(prev => [...prev, userMessage]);
    setPromptInput('');
    setIsProcessing(true);
    setError('');

    // Add assistant message placeholder
    setMessages(prev => [...prev, {
      id: `response-${Date.now()}`,
      role: 'assistant',
      content: '',
      timestamp: new Date(),
    }]);

    // Emit prompt to backend
    socketClient.emitServer('submitPrompt', promptInput.trim());
  };

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

  if (loading) {
    return (
      <div className="flex-1 flex items-center justify-center bg-bg-primary">
        <p className="text-text-muted">Loading chat session...</p>
      </div>
    );
  }

  if (error && !session) {
    return (
      <div className="flex-1 flex items-center justify-center bg-bg-primary">
        <div className="text-center">
          <p className="text-red-500 mb-4">{error}</p>
          <button
            onClick={() => navigate(`/projects/${projectId}`)}
            className="px-4 py-2 bg-brand text-white rounded hover:bg-red-700 transition-colors"
          >
            Back to Project
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="flex-1 flex bg-bg-primary overflow-hidden">
      {/* Main Chat Area */}
      <div className="flex-1 flex flex-col">
        {/* Messages */}
        <div className="flex-1 overflow-y-auto p-4 space-y-4">
          {messages.map((message) => (
            <ChatMessageBubble key={message.id} message={message} />
          ))}
          <div ref={messagesEndRef} />
        </div>

        {/* Prompt Input */}
        <div className="border-t border-border-subtle p-4 bg-bg-secondary">
          <form onSubmit={handleSubmitPrompt} className="flex gap-2">
            <textarea
              ref={inputRef}
              value={promptInput}
              onChange={(e) => setPromptInput(e.target.value)}
              onKeyDown={(e) => {
                if (e.key === 'Enter' && !e.shiftKey) {
                  e.preventDefault();
                  handleSubmitPrompt(e);
                }
              }}
              placeholder="Enter your prompt... (Shift+Enter for new line)"
              className="flex-1 px-3 py-2 bg-bg-tertiary border border-border-default rounded text-text-primary focus:border-brand focus:outline-none resize-none"
              rows={3}
              disabled={isProcessing}
            />
            <button
              type="submit"
              disabled={isProcessing || !promptInput.trim()}
              className="px-6 py-2 bg-brand text-white rounded hover:bg-red-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            >
              {isProcessing ? 'Processing...' : 'Send'}
            </button>
          </form>
        </div>
      </div>

      {/* Session Sidebar */}
      <div className="w-80 border-l border-border-subtle bg-bg-secondary flex flex-col overflow-y-auto">
        <SessionSidebar session={session} project={project} />
      </div>
    </div>
  );
}

function ChatMessageBubble({ message }: { message: ChatMessage }) {
  const [thinkingExpanded, setThinkingExpanded] = useState(false);

  return (
    <div
      className={`max-w-3xl ${
        message.role === 'user' ? 'ml-auto' : ''
      }`}
    >
      <div
        className={`rounded p-4 ${
          message.role === 'user'
            ? 'bg-brand text-white'
            : 'bg-bg-tertiary border border-border-default'
        }`}
      >
        {message.role === 'assistant' && message.thinking && (
          <div className="mb-3">
            <button
              onClick={() => setThinkingExpanded(!thinkingExpanded)}
              className="text-xs text-text-muted hover:text-text-secondary flex items-center gap-1"
            >
              <span className={`transform transition-transform ${thinkingExpanded ? 'rotate-90' : ''}`}>▶</span>
              Thinking ({message.thinking.length} chars)
            </button>
            {thinkingExpanded && (
              <div className="mt-2 p-3 bg-bg-secondary rounded text-sm text-text-secondary whitespace-pre-wrap">
                {message.thinking}
              </div>
            )}
          </div>
        )}

        <div className="whitespace-pre-wrap">{message.content}</div>

        {message.toolCalls && message.toolCalls.length > 0 && (
          <div className="mt-3 space-y-2">
            {message.toolCalls.map((toolCall, idx) => (
              <div
                key={toolCall.callId || idx}
                className="p-2 bg-bg-secondary rounded border border-border-default"
              >
                <div className="text-xs font-mono text-text-secondary">
                  <span className="text-brand">⚡</span> {toolCall.name}
                  {toolCall.response && (
                    <span className="ml-2 text-green-500">✓</span>
                  )}
                </div>
              </div>
            ))}
          </div>
        )}

        <div className="mt-2 text-xs text-text-muted">
          {message.timestamp.toLocaleTimeString()}
        </div>
      </div>
    </div>
  );
}

function SessionSidebar({ session, project }: { session: ChatSession | null; project: Project | null }) {
  if (!session) {
    return (
      <div className="p-4">
        <p className="text-text-muted">No session loaded</p>
      </div>
    );
  }

  return (
    <div className="p-4 space-y-4">
      <div>
        <h3 className="text-sm font-semibold text-text-secondary uppercase tracking-wider mb-2">
          Session
        </h3>
        <div className="space-y-2">
          <div>
            <div className="text-xs text-text-muted">Name</div>
            <div className="text-text-primary">{session.name}</div>
          </div>
          <div>
            <div className="text-xs text-text-muted">ID</div>
            <div className="font-mono text-xs text-text-secondary truncate">
              {session._id}
            </div>
          </div>
          <div>
            <div className="text-xs text-text-muted">Mode</div>
            <div className="text-text-primary capitalize">{session.mode}</div>
          </div>
        </div>
      </div>

      <div className="border-t border-border-subtle pt-4">
        <h3 className="text-sm font-semibold text-text-secondary uppercase tracking-wider mb-2">
          Model
        </h3>
        <div className="text-text-primary">
          {session.selectedModel}
        </div>
        <div className="text-xs text-text-muted mt-1">
          Provider: {typeof session.provider === 'string' ? 'Loaded' : session.provider?.name}
        </div>
      </div>

      <div className="border-t border-border-subtle pt-4">
        <h3 className="text-sm font-semibold text-text-secondary uppercase tracking-wider mb-2">
          Stats
        </h3>
        <div className="grid grid-cols-3 gap-2 text-center">
          <div>
            <div className="text-xs text-text-muted">TC</div>
            <div className="text-lg font-mono">{session.stats.toolCallCount}</div>
          </div>
          <div>
            <div className="text-xs text-text-muted">FO</div>
            <div className="text-lg font-mono">0</div>
          </div>
          <div>
            <div className="text-xs text-text-muted">SA</div>
            <div className="text-lg font-mono">0</div>
          </div>
        </div>
      </div>

      <div className="border-t border-border-subtle pt-4">
        <h3 className="text-sm font-semibold text-text-secondary uppercase tracking-wider mb-2">
          Project
        </h3>
        {project ? (
          <div className="space-y-1">
            <div className="text-text-primary">{project.name}</div>
            <div className="font-mono text-xs text-text-secondary">{project.slug}</div>
          </div>
        ) : (
          <div className="text-text-muted text-sm">Loading...</div>
        )}
      </div>
    </div>
  );
}
