import { useState, useEffect, useRef, useCallback } from 'react';
import { useChatStore, Message } from '../store/chatStore';
import { useGatewayStore } from '../store/gatewayStore';
import { Send, Paperclip, ChevronDown, Terminal, Loader2, SquarePen } from 'lucide-react';

const MODELS = ['glm-5', 'qwen3.5-plus', 'kimi-k2.5', 'minimax-m2.5'];

export function ChatArea() {
  const {
    messages, currentAgent, isStreaming, currentModel,
    sendMessage: sendToGateway, setCurrentModel, initStreamListener,
    newConversation,
  } = useChatStore();
  const { connectionState } = useGatewayStore();

  const [input, setInput] = useState('');
  const [showModelPicker, setShowModelPicker] = useState(false);
  const scrollRef = useRef<HTMLDivElement>(null);
  const textareaRef = useRef<HTMLTextAreaElement>(null);

  // Auto-resize textarea
  const adjustTextarea = useCallback(() => {
    const el = textareaRef.current;
    if (el) {
      el.style.height = 'auto';
      el.style.height = Math.min(el.scrollHeight, 160) + 'px';
    }
  }, []);

  // Init agent stream listener on mount
  useEffect(() => {
    const unsub = initStreamListener();
    return unsub;
  }, []);

  // Auto-scroll to bottom on new messages
  useEffect(() => {
    if (scrollRef.current) {
      scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
    }
  }, [messages]);

  const handleSend = () => {
    if (!input.trim() || isStreaming) return;
    sendToGateway(input);
    setInput('');
  };

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

  const connected = connectionState === 'connected';

  return (
    <>
      {/* Header */}
      <div className="h-14 border-b border-gray-100 flex items-center justify-between px-6 flex-shrink-0">
        <div className="flex items-center gap-2">
          <h2 className="font-semibold text-gray-900">{currentAgent?.name || 'ZCLAW'}</h2>
          <span className={`text-xs flex items-center gap-1 ${connected ? 'text-green-500' : 'text-gray-400'}`}>
            <span className={`w-1.5 h-1.5 rounded-full ${connected ? 'bg-green-400' : 'bg-gray-300'}`}></span>
            {connected ? 'Gateway 已连接' : 'Gateway 未连接'}
          </span>
        </div>
        <div className="flex items-center gap-2">
          {messages.length > 0 && (
            <button
              onClick={newConversation}
              className="flex items-center gap-1.5 px-3 py-1.5 text-xs text-gray-500 hover:text-orange-600 hover:bg-orange-50 rounded-lg transition-colors"
              title="新对话"
            >
              <SquarePen className="w-3.5 h-3.5" />
              新对话
            </button>
          )}
        </div>
      </div>

      {/* Messages */}
      <div ref={scrollRef} className="flex-1 overflow-y-auto custom-scrollbar p-6 space-y-4">
        {messages.length === 0 && (
          <div className="text-center text-gray-400 py-20">
            <p className="text-lg mb-2">欢迎使用 ZCLAW 🦞</p>
            <p className="text-sm">{connected ? '发送消息开始对话' : '请先在设置中连接 Gateway'}</p>
          </div>
        )}

        {messages.map((message) => (
          <MessageBubble key={message.id} message={message} />
        ))}

        {isStreaming && (
          <div className="flex items-center gap-2 text-gray-400 text-xs pl-12">
            <Loader2 className="w-3 h-3 animate-spin" />
            Agent 思考中...
          </div>
        )}
      </div>

      {/* Input */}
      <div className="border-t border-gray-100 p-4 bg-white">
        <div className="max-w-4xl mx-auto">
          <div className="relative flex items-end gap-2 bg-gray-50 rounded-2xl border border-gray-200 p-2 focus-within:border-orange-300 focus-within:ring-2 focus-within:ring-orange-100 transition-all">
            <button className="p-2 text-gray-400 hover:text-gray-600 rounded-lg">
              <Paperclip className="w-5 h-5" />
            </button>
            <div className="flex-1 py-1">
              <textarea
                ref={textareaRef}
                value={input}
                onChange={(e) => { setInput(e.target.value); adjustTextarea(); }}
                onKeyDown={handleKeyDown}
                placeholder={isStreaming ? 'Agent 正在回复...' : '发送给 ZCLAW（Shift+Enter 换行）'}
                disabled={isStreaming}
                rows={1}
                className="w-full bg-transparent border-none focus:outline-none text-gray-700 placeholder-gray-400 disabled:opacity-50 resize-none leading-relaxed"
                style={{ minHeight: '24px', maxHeight: '160px' }}
              />
            </div>
            <div className="flex items-center gap-2 pr-2 pb-1 relative">
              <button
                onClick={() => setShowModelPicker(!showModelPicker)}
                className="flex items-center gap-1 px-2 py-1 text-xs text-gray-500 hover:bg-gray-200 rounded-md transition-colors"
              >
                <span>{currentModel}</span>
                <ChevronDown className="w-3 h-3" />
              </button>
              {showModelPicker && (
                <div className="absolute bottom-full right-8 mb-2 bg-white border border-gray-200 rounded-lg shadow-lg py-1 min-w-[160px] z-10">
                  {MODELS.map((model) => (
                    <button
                      key={model}
                      onClick={() => { setCurrentModel(model); setShowModelPicker(false); }}
                      className={`w-full text-left px-3 py-2 text-xs hover:bg-gray-50 ${model === currentModel ? 'text-orange-600 font-medium' : 'text-gray-700'}`}
                    >
                      {model}
                    </button>
                  ))}
                </div>
              )}
              <button
                onClick={handleSend}
                disabled={isStreaming || !input.trim()}
                className="w-8 h-8 bg-gray-900 text-white rounded-full flex items-center justify-center hover:bg-gray-800 transition-colors disabled:opacity-40 disabled:cursor-not-allowed"
              >
                <Send className="w-4 h-4" />
              </button>
            </div>
          </div>
          <div className="text-center mt-2 text-xs text-gray-400">
            Agent 在本地运行，内容由 AI 生成
          </div>
        </div>
      </div>
    </>
  );
}

/** Lightweight markdown renderer — handles code blocks, inline code, bold, italic, links */
function renderMarkdown(text: string): React.ReactNode[] {
  const nodes: React.ReactNode[] = [];
  const lines = text.split('\n');
  let i = 0;

  while (i < lines.length) {
    const line = lines[i];

    // Fenced code block
    if (line.startsWith('```')) {
      const lang = line.slice(3).trim();
      const codeLines: string[] = [];
      i++;
      while (i < lines.length && !lines[i].startsWith('```')) {
        codeLines.push(lines[i]);
        i++;
      }
      i++; // skip closing ```
      nodes.push(
        <pre key={nodes.length} className="bg-gray-900 text-gray-100 rounded-lg p-3 my-2 overflow-x-auto text-xs font-mono leading-relaxed">
          {lang && <div className="text-gray-500 text-[10px] mb-1 uppercase">{lang}</div>}
          <code>{codeLines.join('\n')}</code>
        </pre>
      );
      continue;
    }

    // Normal line — parse inline markdown
    nodes.push(
      <span key={nodes.length}>
        {i > 0 && lines[i - 1] !== undefined && !nodes[nodes.length - 1]?.toString().includes('pre') && '\n'}
        {renderInline(line)}
      </span>
    );
    i++;
  }

  return nodes;
}

function renderInline(text: string): React.ReactNode[] {
  const parts: React.ReactNode[] = [];
  // Pattern: **bold**, *italic*, `code`, [text](url)
  const regex = /(\*\*(.+?)\*\*)|(\*(.+?)\*)|(`(.+?)`)|(\[(.+?)\]\((.+?)\))/g;
  let lastIndex = 0;
  let match: RegExpExecArray | null;

  while ((match = regex.exec(text)) !== null) {
    // Text before match
    if (match.index > lastIndex) {
      parts.push(text.slice(lastIndex, match.index));
    }

    if (match[1]) {
      // **bold**
      parts.push(<strong key={parts.length} className="font-semibold">{match[2]}</strong>);
    } else if (match[3]) {
      // *italic*
      parts.push(<em key={parts.length}>{match[4]}</em>);
    } else if (match[5]) {
      // `code`
      parts.push(
        <code key={parts.length} className="bg-gray-100 text-orange-700 px-1 py-0.5 rounded text-[0.85em] font-mono">
          {match[6]}
        </code>
      );
    } else if (match[7]) {
      // [text](url)
      parts.push(
        <a key={parts.length} href={match[9]} target="_blank" rel="noopener noreferrer"
          className="text-orange-600 underline hover:text-orange-700">{match[8]}</a>
      );
    }

    lastIndex = match.index + match[0].length;
  }

  if (lastIndex < text.length) {
    parts.push(text.slice(lastIndex));
  }

  return parts.length > 0 ? parts : [text];
}

function MessageBubble({ message }: { message: Message }) {
  if (message.role === 'tool') {
    return (
      <div className="ml-12 bg-gray-50 border border-gray-200 rounded-lg p-3 text-xs font-mono">
        <div className="flex items-center gap-2 text-gray-500 mb-1">
          <Terminal className="w-3.5 h-3.5" />
          <span className="font-semibold">{message.toolName || 'tool'}</span>
        </div>
        {message.toolInput && (
          <pre className="text-gray-600 bg-white rounded p-2 mb-1 overflow-x-auto">{message.toolInput}</pre>
        )}
        {message.content && (
          <pre className="text-green-700 bg-white rounded p-2 overflow-x-auto">{message.content}</pre>
        )}
      </div>
    );
  }

  const isUser = message.role === 'user';

  return (
    <div className={`flex gap-4 ${isUser ? 'justify-end' : ''}`}>
      <div
        className={`w-8 h-8 rounded-lg flex items-center justify-center flex-shrink-0 ${isUser ? 'bg-gray-200 text-gray-600 order-last' : 'agent-avatar text-white'}`}
      >
        {isUser ? '用' : '🦞'}
      </div>
      <div className={isUser ? 'max-w-2xl' : 'flex-1 max-w-3xl'}>
        <div className={`p-4 shadow-sm ${isUser ? 'chat-bubble-user shadow-md' : 'chat-bubble-assistant'}`}>
          <div className={`leading-relaxed whitespace-pre-wrap ${isUser ? 'text-white' : 'text-gray-700'}`}>
            {message.content
              ? (isUser ? message.content : renderMarkdown(message.content))
              : (message.streaming ? '' : '...')}
            {message.streaming && <span className="inline-block w-1.5 h-4 bg-orange-500 animate-pulse ml-0.5 align-text-bottom rounded-sm" />}
          </div>
          {message.error && (
            <p className="text-xs text-red-500 mt-2">{message.error}</p>
          )}
        </div>
      </div>
    </div>
  );
}
