import { useState, useRef, useEffect, useCallback } from 'react';
import { useAuth } from '../../hooks/useAuth';

interface ChatMessage {
  role: 'user' | 'assistant';
  content: string;
  timestamp: number;
  isStreaming?: boolean;
}

const AI_CHAT_URL = '/api/prediction-chat';

/** assistant 메시지에서 thinking(JSON tool call, 구분선 등)과 답변을 분리 */
function splitThinking(content: string): { thinking: string; answer: string } {
  // 패턴: ```json...``` 블록 + ---\n_데이터 조회 완료..._\n\n 까지가 thinking
  const thinkingPattern = /^([\s\S]*?```json[\s\S]*?```[\s\S]*?---\n_[^_]*_\n*)/;
  const match = content.match(thinkingPattern);
  if (match) {
    return { thinking: match[1].trim(), answer: content.slice(match[0].length).trim() };
  }
  // ```json 블록만 있고 답변이 아직 안 온 경우 (스트리밍 중)
  const jsonOnly = /^([\s\S]*```json[\s\S]*?```[\s\S]*)$/;
  const m2 = content.match(jsonOnly);
  if (m2 && !content.includes('---')) {
    return { thinking: m2[1].trim(), answer: '' };
  }
  return { thinking: '', answer: content };
}

export function AiChatPanel() {
  const { user } = useAuth();
  const userId = user?.email ?? 'anonymous';

  const [isOpen, setIsOpen] = useState(true);
  const [messages, setMessages] = useState<ChatMessage[]>([]);
  const [input, setInput] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [elapsed, setElapsed] = useState(0);
  const timerRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const [expanded, setExpanded] = useState(false);
  const [historyLoaded, setHistoryLoaded] = useState(false);
  const messagesEndRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const abortRef = useRef<AbortController | null>(null);

  // 마운트 시 Redis에서 대화 히스토리 로드
  useEffect(() => {
    if (historyLoaded) return;
    fetch(`${AI_CHAT_URL}/history?user_id=${encodeURIComponent(userId)}`)
      .then(res => res.ok ? res.json() : [])
      .then((history: { role: string; content: string }[]) => {
        if (history.length > 0) {
          setMessages(history.map(m => ({
            role: m.role as 'user' | 'assistant',
            content: m.content,
            timestamp: Date.now(),
          })));
        }
      })
      .catch(() => { /* Redis 미연결 시 무시 */ })
      .finally(() => setHistoryLoaded(true));
  }, [userId, historyLoaded]);

  useEffect(() => {
    if (isLoading) {
      setElapsed(0);
      timerRef.current = setInterval(() => setElapsed(s => s + 1), 1000);
    } else if (timerRef.current) {
      clearInterval(timerRef.current);
      timerRef.current = null;
    }
    return () => { if (timerRef.current) clearInterval(timerRef.current); };
  }, [isLoading]);

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

  useEffect(() => {
    if (isOpen) inputRef.current?.focus();
  }, [isOpen]);

  const sendMessage = useCallback(async () => {
    if (!input.trim() || isLoading) return;

    const userMsg: ChatMessage = { role: 'user', content: input.trim(), timestamp: Date.now() };
    setMessages(prev => [...prev, userMsg]);
    setInput('');
    setIsLoading(true);

    // 스트리밍 placeholder 추가
    const streamingMsg: ChatMessage = { role: 'assistant', content: '', timestamp: Date.now(), isStreaming: true };
    setMessages(prev => [...prev, streamingMsg]);

    const controller = new AbortController();
    abortRef.current = controller;

    try {
      const res = await fetch(AI_CHAT_URL, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          message: userMsg.content,
          user_id: userId,
          stream: true,
        }),
        signal: controller.signal,
      });

      if (!res.ok) throw new Error(`서버 오류: ${res.status}`);
      if (!res.body) throw new Error('스트리밍 미지원');

      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let accumulated = '';
      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: ')) continue;
          const data = line.slice(6);
          if (data === '[DONE]') break;

          try {
            const chunk = JSON.parse(data) as { content: string; done: boolean };
            accumulated += chunk.content;

            setMessages(prev => {
              const updated = [...prev];
              updated[updated.length - 1] = {
                ...updated[updated.length - 1],
                content: accumulated,
              };
              return updated;
            });

            if (chunk.done) break;
          } catch {
            // JSON 파싱 실패 무시
          }
        }
      }

      // 스트리밍 완료
      setMessages(prev => {
        const updated = [...prev];
        updated[updated.length - 1] = {
          ...updated[updated.length - 1],
          isStreaming: false,
        };
        return updated;
      });
    } catch (err) {
      if ((err as Error).name === 'AbortError') return;
      setMessages(prev => {
        const updated = [...prev];
        updated[updated.length - 1] = {
          role: 'assistant',
          content: `오류: ${err instanceof Error ? err.message : 'AI 서버 연결 실패'}`,
          timestamp: Date.now(),
          isStreaming: false,
        };
        return updated;
      });
    } finally {
      setIsLoading(false);
      abortRef.current = null;
    }
  }, [input, isLoading, userId]);

  const clearHistory = useCallback(async () => {
    setMessages([]);
    try {
      await fetch(`${AI_CHAT_URL}/history?user_id=${encodeURIComponent(userId)}`, { method: 'DELETE' });
    } catch { /* 무시 */ }
  }, [userId]);

  const quickQuestions = [
    '현재 해양 상황을 요약해줘',
    '중국어선 불법조업 의심 분석해줘',
    '위험 선박 상위 10척 알려줘',
    '다크베셀 현황 분석해줘',
  ];

  return (
    <div style={{
      ...(expanded ? {
        position: 'fixed' as const,
        bottom: 16,
        right: 16,
        width: 520,
        height: 600,
        zIndex: 9999,
        borderRadius: 8,
        boxShadow: '0 8px 32px rgba(0,0,0,0.6)',
        display: 'flex',
        flexDirection: 'column' as const,
        background: 'rgba(12,24,37,0.97)',
        border: '1px solid rgba(168,85,247,0.3)',
      } : {
        borderTop: '1px solid rgba(168,85,247,0.2)',
        marginTop: 8,
      }),
    }}>
      {/* Toggle header */}
      <div
        onClick={() => {
          if (!isOpen) { setIsOpen(true); return; }
          if (expanded) { setExpanded(false); return; }
          setExpanded(true);
        }}
        style={{
          display: 'flex', alignItems: 'center', gap: 6,
          padding: '6px 8px', cursor: 'pointer',
          background: isOpen ? 'rgba(168,85,247,0.12)' : 'rgba(168,85,247,0.04)',
          borderRadius: expanded ? '8px 8px 0 0' : 4,
          borderLeft: expanded ? 'none' : '2px solid rgba(168,85,247,0.5)',
          flexShrink: 0,
        }}
      >
        <span style={{ fontSize: 12 }}>🤖</span>
        <span style={{ fontSize: 11, fontWeight: 700, color: '#c4b5fd' }}>AI 해양분석</span>
        <span style={{ fontSize: 8, color: '#8b5cf6', marginLeft: 2, background: 'rgba(139,92,246,0.15)', padding: '1px 5px', borderRadius: 3 }}>
          Qwen3 14B
        </span>
        <span style={{ marginLeft: 'auto', display: 'flex', gap: 4, alignItems: 'center' }}>
          {isOpen && (
            <button
              onClick={e => { e.stopPropagation(); setIsOpen(false); setExpanded(false); }}
              title="접기"
              style={{
                background: 'none', border: 'none', cursor: 'pointer',
                fontSize: 8, color: '#8b5cf6',
                padding: '8px 10px', margin: '-8px -8px -8px -6px',
                lineHeight: 1,
              }}
            >
              {expanded ? '⊖' : '▼'}
            </button>
          )}
          {!isOpen && (
            <span style={{ fontSize: 8, color: '#8b5cf6' }}>▶</span>
          )}
        </span>
      </div>

      {/* Chat body */}
      {isOpen && (
        <div style={{
          display: 'flex', flexDirection: 'column',
          ...(expanded ? { flex: 1 } : { height: 360 }),
          background: expanded ? 'transparent' : 'rgba(88,28,135,0.08)',
          borderRadius: '0 0 6px 6px', overflow: 'hidden',
          borderLeft: expanded ? 'none' : '2px solid rgba(168,85,247,0.3)',
          borderBottom: expanded ? 'none' : '1px solid rgba(168,85,247,0.15)',
        }}>
          {/* Messages */}
          <div style={{
            flex: 1, overflowY: 'auto', padding: '6px 8px',
            display: 'flex', flexDirection: 'column', gap: 6,
          }}>
            {messages.length === 0 && (
              <div style={{ padding: '12px 0', textAlign: 'center' }}>
                <div style={{ fontSize: 10, color: '#a78bfa', marginBottom: 8 }}>
                  해양 상황에 대해 질문하세요
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                  {quickQuestions.map((q, i) => (
                    <button
                      key={i}
                      onClick={() => { setInput(q); }}
                      style={{
                        background: 'rgba(139,92,246,0.08)',
                        border: '1px solid rgba(139,92,246,0.25)',
                        borderRadius: 4, padding: '4px 8px',
                        fontSize: 9, color: '#a78bfa',
                        cursor: 'pointer', textAlign: 'left',
                      }}
                    >
                      {q}
                    </button>
                  ))}
                </div>
              </div>
            )}
            {messages.map((msg, i) => {
              const isAssistant = msg.role === 'assistant';
              const { thinking, answer } = isAssistant ? splitThinking(msg.content) : { thinking: '', answer: msg.content };
              const displayText = isAssistant ? (answer || (thinking && !msg.isStreaming ? '' : msg.content)) : msg.content;

              return (
                <div
                  key={i}
                  style={{
                    alignSelf: msg.role === 'user' ? 'flex-end' : 'flex-start',
                    maxWidth: '85%',
                  }}
                >
                  {/* thinking 접기 블록 */}
                  {isAssistant && thinking && (
                    <details style={{
                      background: 'rgba(100,116,139,0.1)',
                      borderRadius: '6px 6px 0 0',
                      padding: '4px 8px',
                      fontSize: 9,
                      color: '#64748b',
                      cursor: 'pointer',
                      borderLeft: '2px solid rgba(139,92,246,0.3)',
                    }}>
                      <summary style={{ userSelect: 'none', outline: 'none' }}>도구 호출</summary>
                      <pre style={{
                        margin: '4px 0 0', padding: '4px',
                        fontSize: 8, color: '#94a3b8',
                        whiteSpace: 'pre-wrap', wordBreak: 'break-all',
                        background: 'rgba(0,0,0,0.2)', borderRadius: 3,
                        maxHeight: 120, overflowY: 'auto',
                      }}>{thinking}</pre>
                    </details>
                  )}
                  {/* 메시지 본문 */}
                  <div style={{
                    background: msg.role === 'user'
                      ? 'rgba(139,92,246,0.25)'
                      : 'rgba(168,85,247,0.08)',
                    borderRadius: thinking
                      ? '0 0 8px 8px'
                      : (msg.role === 'user' ? '8px 8px 2px 8px' : '8px 8px 8px 2px'),
                    padding: '6px 8px',
                    fontSize: 10,
                    color: '#e2e8f0',
                    lineHeight: 1.5,
                    whiteSpace: 'pre-wrap',
                    wordBreak: 'break-word',
                  }}>
                    {displayText}
                    {msg.isStreaming && msg.content && (
                      <span style={{ color: '#a78bfa' }}>
                        <span style={{ animation: 'pulse 1s infinite' }}> ▋</span>
                        <span style={{ fontSize: 8, color: '#64748b', marginLeft: 4, fontVariantNumeric: 'tabular-nums' }}>
                          {String(Math.floor(elapsed / 60)).padStart(2, '0')}:{String(elapsed % 60).padStart(2, '0')}
                        </span>
                      </span>
                    )}
                  </div>
                </div>
              );
            })}
            {isLoading && !messages[messages.length - 1]?.content && (
              <div style={{
                alignSelf: 'flex-start', padding: '6px 8px',
                background: 'rgba(168,85,247,0.08)', borderRadius: 8,
                fontSize: 10, color: '#a78bfa',
                display: 'flex', alignItems: 'center', gap: 6,
              }}>
                <span style={{ animation: 'pulse 1.5s ease-in-out infinite' }}>분석 중</span>
                <span style={{ color: '#64748b', fontVariantNumeric: 'tabular-nums' }}>
                  {String(Math.floor(elapsed / 60)).padStart(2, '0')}:{String(elapsed % 60).padStart(2, '0')}
                </span>
              </div>
            )}
            <div ref={messagesEndRef} />
          </div>

          {/* Input */}
          <div style={{
            display: 'flex', gap: 4, padding: '6px 8px',
            borderTop: '1px solid rgba(255,255,255,0.06)',
            background: 'rgba(0,0,0,0.15)',
          }}>
            {messages.length > 0 && (
              <button
                onClick={clearHistory}
                title="대화 초기화"
                style={{
                  background: 'none', border: 'none',
                  color: '#64748b', fontSize: 12, cursor: 'pointer',
                  padding: '0 4px', flexShrink: 0,
                }}
              >
                ↺
              </button>
            )}
            <input
              ref={inputRef}
              value={input}
              onChange={e => setInput(e.target.value)}
              onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); void sendMessage(); } }}
              placeholder="해양 상황 질문..."
              disabled={isLoading}
              style={{
                flex: 1, background: 'rgba(139,92,246,0.06)',
                border: '1px solid rgba(139,92,246,0.2)',
                borderRadius: 4, padding: '5px 8px',
                fontSize: 10, color: '#e2e8f0', outline: 'none',
              }}
            />
            <button
              onClick={() => { void sendMessage(); }}
              disabled={isLoading || !input.trim()}
              style={{
                background: isLoading || !input.trim() ? '#334155' : '#7c3aed',
                border: 'none', borderRadius: 4,
                padding: '4px 10px', fontSize: 10, fontWeight: 700,
                color: '#fff', cursor: isLoading ? 'not-allowed' : 'pointer',
              }}
            >
              전송
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
