import React, { useState, useRef, useEffect } from 'react';
import ReactMarkdown from 'react-markdown';
import { FaUser, FaRobot, FaSpinner } from 'react-icons/fa';
import axios from 'axios';

interface Message {
  role: 'user' | 'assistant';
  content: string;
}

const ChatPanel: React.FC<{ projectPath: string; model: string }> = ({ projectPath, model }) => {
  const [messages, setMessages] = useState<Message[]>([]);
  const [input, setInput] = useState('');
  const [loading, setLoading] = useState(false);
  const [mentionQuery, setMentionQuery] = useState('');
  const [mentionItems, setMentionItems] = useState<any[]>([]);
  const [showMentions, setShowMentions] = useState(false);
  const [contextFiles, setContextFiles] = useState<string[]>([]);
  const chatEnd = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const send = async () => {
    if (!input.trim() || loading) return;
    const userMsg = input;
    setInput('');
    setMessages(prev => [...prev, { role: 'user', content: userMsg }]);
    setLoading(true);

    const assistantMsgRef = { current: '' };
    setMessages(prev => [...prev, { role: 'assistant', content: '' }]);

    try {
      const response = await fetch('/api/chat', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          messages: [...messages, { role: 'user', content: userMsg }],
          project_path: projectPath,
          model: model,
          context_files: contextFiles,
        }),
      });

      if (!response.ok) throw new Error(`Server responded with ${response.status}`);

      const reader = response.body?.getReader();
      if (!reader) throw new Error('No response body');

      const decoder = new TextDecoder();
      let buffer = '';

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';
        for (const line of lines) {
          if (line.startsWith('data: ')) {
            const data = line.slice(6);
            if (data === '[DONE]') break;
            try {
              const { token } = JSON.parse(data);
              if (token.startsWith('ERROR:')) {
                assistantMsgRef.current = `❌ ${token.substring(7)}`;
                setMessages(prev => {
                  const copy = [...prev];
                  copy[copy.length - 1] = { role: 'assistant', content: assistantMsgRef.current };
                  return copy;
                });
                return;
              }
              assistantMsgRef.current += token;
              setMessages(prev => {
                const copy = [...prev];
                copy[copy.length - 1] = { role: 'assistant', content: assistantMsgRef.current };
                return copy;
              });
            } catch (e) {
              assistantMsgRef.current = `Parse error: ${data}`;
              setMessages(prev => {
                const copy = [...prev];
                copy[copy.length - 1] = { role: 'assistant', content: assistantMsgRef.current };
                return copy;
              });
              return;
            }
          }
        }
      }
    } catch (err: any) {
      setMessages(prev => {
        const copy = [...prev];
        copy[copy.length - 1] = { role: 'assistant', content: `❌ ${err.message}` };
        return copy;
      });
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => { chatEnd.current?.scrollIntoView({ behavior: 'smooth' }); }, [messages]);

  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;
    setInput(value);

    const atIndex = value.lastIndexOf('@');
    if (atIndex !== -1 && (atIndex === 0 || value[atIndex - 1] === ' ')) {
      const query = value.slice(atIndex + 1).toLowerCase();
      setMentionQuery(query);

      if ('git'.startsWith(query)) {
        setMentionItems([{ name: 'git (current diff)', type: 'special', path: '__git__' }]);
        setShowMentions(true);
        return;
      }

      axios.get('/api/files', { params: { project_path: projectPath } })
        .then(res => {
          const flatten = (nodes: any[]): any[] => {
            let result: any[] = [];
            for (const node of nodes) {
              if (node.name.toLowerCase().includes(query))
                result.push(node);
              if (node.children) result = result.concat(flatten(node.children));
            }
            return result;
          };
          const matches = flatten(res.data).slice(0, 5);
          setMentionItems(matches);
          setShowMentions(matches.length > 0);
        })
        .catch(() => setShowMentions(false));
    } else {
      setShowMentions(false);
    }
  };

  const insertMention = (item: any) => {
    const atIndex = input.lastIndexOf('@');
    const newInput = input.slice(0, atIndex) + item.name + ' ';
    setInput(newInput);
    setShowMentions(false);
    if (item.path === '__git__') {
      if (!contextFiles.includes('__git__')) {
        setContextFiles(prev => [...prev, '__git__']);
      }
    } else if (!contextFiles.includes(item.path)) {
      setContextFiles(prev => [...prev, item.path]);
    }
    inputRef.current?.focus();
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%' }}>
      <div style={{ flex: 1, overflowY: 'auto', padding: 16 }}>
        {messages.map((m, i) => (
          <div key={i} style={{ marginBottom: 16, display: 'flex', justifyContent: m.role === 'user' ? 'flex-end' : 'flex-start' }}>
            <div style={{
              maxWidth: '80%',
              background: m.role === 'user' ? 'var(--accent)' : 'var(--bg-tertiary)',
              color: m.role === 'user' ? 'white' : 'var(--text-primary)',
              borderRadius: 12,
              borderBottomRightRadius: m.role === 'user' ? 4 : 12,
              borderBottomLeftRadius: m.role === 'user' ? 12 : 4,
              padding: 12,
              boxShadow: '0 2px 8px rgba(0,0,0,0.15)'
            }}>
              <div style={{ fontSize: 11, marginBottom: 4, display: 'flex', alignItems: 'center', gap: 4, color: m.role === 'user' ? 'rgba(255,255,255,0.8)' : 'var(--text-secondary)' }}>
                {m.role === 'user' ? <FaUser size={10} /> : <FaRobot size={10} />}
                {m.role === 'user' ? 'You' : 'Codeki'}
              </div>
              <ReactMarkdown>{m.content}</ReactMarkdown>
            </div>
          </div>
        ))}
        {loading && (
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, color: 'var(--text-secondary)', padding: 8 }}>
            <FaSpinner className="spin" /> Codeki is thinking...
          </div>
        )}
        <div ref={chatEnd} />
      </div>
      <div style={{ borderTop: '1px solid var(--border)', padding: 12, background: 'var(--bg-secondary)', position: 'relative' }}>
        {showMentions && (
          <div style={{
            position: 'absolute',
            bottom: '100%',
            left: 0,
            right: 0,
            background: 'var(--bg-tertiary)',
            border: '1px solid var(--border)',
            borderRadius: 4,
            maxHeight: 150,
            overflowY: 'auto',
            marginBottom: 4,
            zIndex: 10,
          }}>
            {mentionItems.map(item => (
              <div
                key={item.path}
                onClick={() => insertMention(item)}
                style={{ padding: '4px 8px', cursor: 'pointer', fontSize: 12, display: 'flex', alignItems: 'center', gap: 6 }}
              >
                {item.type === 'folder' ? '📁' : item.type === 'special' ? '🔗' : '📄'} {item.name}
              </div>
            ))}
          </div>
        )}
        <div style={{ display: 'flex', gap: 8 }}>
          <input
            ref={inputRef}
            style={{ flex: 1 }}
            value={input}
            onChange={handleInputChange}
            onKeyDown={e => e.key === 'Enter' && send()}
            placeholder="Ask anything... Type @ to reference a file or @git"
            disabled={loading}
          />
          <button
            onClick={send}
            disabled={loading}
            style={{
              background: loading ? 'var(--border)' : 'var(--accent)',
              color: 'white',
              padding: '0 20px',
              borderRadius: 6,
              fontWeight: 600,
              transition: 'background 0.2s'
            }}
          >
            {loading ? '...' : 'Send'}
          </button>
        </div>
        {contextFiles.length > 0 && (
          <div style={{ marginTop: 6, display: 'flex', gap: 4, flexWrap: 'wrap' }}>
            {contextFiles.map(f => (
              <span key={f} style={{ background: 'var(--accent)', color: 'white', padding: '2px 8px', borderRadius: 10, fontSize: 11 }}>
                📎 {f === '__git__' ? 'Git Diff' : f.split('/').pop()}
                <span style={{ marginLeft: 4, cursor: 'pointer' }} onClick={() => setContextFiles(prev => prev.filter(x => x !== f))}>×</span>
              </span>
            ))}
          </div>
        )}
      </div>
    </div>
  );
};

export default ChatPanel;