import { useCallback, useEffect, useRef, useState } from "react"
import { ScrollArea } from "@/components/ui/scroll-area"
import { cn } from "@/lib/utils"
import { io, Socket } from "socket.io-client"
import { Terminal, Info, AlertTriangle, CheckCircle2, Clock } from "lucide-react"

export interface LogEntry {
  id: string
  tag: string
  msg: string
  type: 'info' | 'warn' | 'error' | 'success'
  time: number
}

interface LogPanelProps {
  className?: string
  email?: string
}

interface BotLogPayload {
  tag?: string
  msg?: unknown
  type?: LogEntry['type']
  time?: number
}

interface BotErrorPayload {
  message?: string
}

interface BotStatusPayload {
  status?: string
}

export function LogPanel({ className, email }: LogPanelProps) {
  const [logs, setLogs] = useState<LogEntry[]>([])
  const [isConnected, setIsConnected] = useState(false)
  const scrollRef = useRef<HTMLDivElement>(null)
  const socketRef = useRef<Socket | null>(null)
  const retryCountRef = useRef(0)
  const disconnectNotifiedRef = useRef(false)
  const retryNotifiedRef = useRef(false)

  const addLog = useCallback((log: Omit<LogEntry, 'id'>) => {
    setLogs(prev => [...prev.slice(-200), { ...log, id: Math.random().toString(36).slice(2, 11) }])
  }, [])

  const addSystemLog = useCallback((msg: string, type: LogEntry['type'] = 'info') => {
    addLog({ tag: 'System', msg, type, time: Date.now() })
  }, [addLog])

  useEffect(() => {
    if (!email) return
    const loadHistory = async () => {
      try {
        const res = await fetch(`/api/logs?email=${encodeURIComponent(email)}`)
        if (!res.ok) return
        const data = await res.json()
        if (!Array.isArray(data.logs)) return
        const normalized = data.logs.map((entry: LogEntry) => ({
          id: entry.id || Math.random().toString(36).slice(2, 11),
          tag: entry.tag || 'System',
          msg: entry.msg || '',
          type: entry.type || 'info',
          time: entry.time || Date.now()
        }))
        setLogs(normalized)
      } catch {
        addSystemLog('历史日志加载失败', 'warn')
      }
    }
    loadHistory()

    // Connect to WebSocket
    // In production this should be an env var, here we assume same host
    const socket = io('/', {
      transports: ['websocket'],
      reconnectionAttempts: 3,
      reconnectionDelay: 1000,
      reconnectionDelayMax: 3000
    })

    socketRef.current = socket

    socket.on('connect', () => {
      setIsConnected(true)
      retryCountRef.current = 0
      disconnectNotifiedRef.current = false
      retryNotifiedRef.current = false
      addSystemLog('已连接到农场服务器')
    })

    socket.on('disconnect', () => {
      setIsConnected(false)
      if (!disconnectNotifiedRef.current) {
        disconnectNotifiedRef.current = true
        addSystemLog('与服务器断开连接', 'warn')
      }
    })

    socket.on('reconnect_attempt', (attempt: number) => {
      retryCountRef.current = attempt
      if (!retryNotifiedRef.current) {
        retryNotifiedRef.current = true
        addSystemLog('连接断开，正在重试（最多3次）', 'warn')
      }
    })

    socket.on('reconnect_failed', () => {
      addSystemLog('连接失败，请重新绑定', 'error')
    })

    socket.on(`bot-log-${email}`, (data: unknown) => {
      const payload = (typeof data === 'object' && data !== null ? data : {}) as BotLogPayload
      // 格式化日志内容（如果它是对象）
      const rawMsg = payload.msg
      let message = ''
      if (typeof rawMsg === 'string') {
        message = rawMsg
      } else if (rawMsg === null || rawMsg === undefined) {
        message = ''
      } else if (typeof rawMsg === 'object') {
        try {
          message = JSON.stringify(rawMsg)
        } catch {
          message = String(rawMsg)
        }
      } else {
        message = String(rawMsg)
      }
      
      const normalizedType: LogEntry['type'] =
        payload.type === 'info' || payload.type === 'warn' || payload.type === 'error' || payload.type === 'success'
          ? payload.type
          : 'info'

      addLog({
        tag: payload.tag || 'System',
        msg: message,
        type: normalizedType,
        time: payload.time || Date.now()
      })
    })

    socket.on(`bot-error-${email}`, (data: unknown) => {
      const payload = (typeof data === 'object' && data !== null ? data : {}) as BotErrorPayload
      addLog({
        tag: 'Error',
        msg: payload.message || '未知错误',
        type: 'error',
        time: Date.now()
      })
    })

    socket.on(`bot-status-${email}`, (data: unknown) => {
      const payload = (typeof data === 'object' && data !== null ? data : {}) as BotStatusPayload
      const statusText = payload.status || 'unknown'
      addSystemLog(`Bot状态更新: ${statusText}`, statusText === 'running' ? 'success' : 'warn')
    })

    return () => {
      socket.off(`bot-log-${email}`)
      socket.off(`bot-error-${email}`)
      socket.off(`bot-status-${email}`)
      socket.off('connect')
      socket.off('disconnect')
      socket.off('reconnect_attempt')
      socket.off('reconnect_failed')
      socket.disconnect()
    }
  }, [email, addLog, addSystemLog])

  // Auto-scroll to bottom
  useEffect(() => {
    if (scrollRef.current) {
      const scrollElement = scrollRef.current.querySelector('[data-radix-scroll-area-viewport]')
      if (scrollElement) {
        scrollElement.scrollTop = scrollElement.scrollHeight
      }
    }
  }, [logs])

  return (
    <div className={cn(
      "flex flex-col h-full bg-white/60 backdrop-blur-md border border-white/50 shadow-sm rounded-3xl overflow-hidden transition-all duration-300",
      className
    )}>
      {/* Header */}
      <div className="flex items-center justify-between px-6 py-4 border-b border-stone-100/50 bg-white/40">
        <div className="flex items-center gap-2">
          <div className="p-1.5 bg-indigo-100 rounded-lg">
            <Terminal className="h-4 w-4 text-indigo-600" />
          </div>
          <h2 className="font-bold text-slate-700">运行日志</h2>
        </div>
        <div className="flex items-center gap-2">
          <span className={cn(
            "h-2 w-2 rounded-full animate-pulse",
            isConnected ? "bg-green-500" : "bg-red-500"
          )} />
          <span className="text-xs text-slate-400 font-medium">
            {isConnected ? 'Live' : 'Offline'}
          </span>
        </div>
      </div>

      {/* Logs Area */}
      <ScrollArea className="flex-1 p-4" ref={scrollRef}>
        <div className="flex flex-col gap-3 min-h-[300px]">
          {logs.length === 0 && (
            <div className="flex flex-col items-center justify-center h-full text-slate-400 py-12 gap-2">
              <Clock className="h-8 w-8 opacity-20" />
              <p className="text-sm font-medium opacity-60">等待活动...</p>
            </div>
          )}
          
          {logs.map((log) => (
            <div 
              key={log.id} 
              className={cn(
                "group flex items-start gap-3 p-3 rounded-2xl text-sm transition-all hover:bg-white/60",
                "border border-transparent hover:border-white/50 hover:shadow-sm animate-in slide-in-from-bottom-2 fade-in duration-300",
                log.type === 'error' && "bg-red-50/50 border-red-100/50",
                log.type === 'warn' && "bg-amber-50/50 border-amber-100/50"
              )}
            >
              {/* Icon */}
              <div className={cn(
                "mt-0.5 shrink-0 h-6 w-6 rounded-full flex items-center justify-center border shadow-sm",
                log.type === 'info' && "bg-white border-slate-100 text-slate-400",
                log.type === 'success' && "bg-green-100 border-green-200 text-green-600",
                log.type === 'warn' && "bg-amber-100 border-amber-200 text-amber-600",
                log.type === 'error' && "bg-red-100 border-red-200 text-red-600"
              )}>
                {log.type === 'info' && <Info className="h-3 w-3" />}
                {log.type === 'success' && <CheckCircle2 className="h-3 w-3" />}
                {log.type === 'warn' && <AlertTriangle className="h-3 w-3" />}
                {log.type === 'error' && <AlertTriangle className="h-3 w-3" />}
              </div>

              {/* Content */}
              <div className="flex-1 min-w-0 space-y-0.5">
                <div className="flex items-center gap-2">
                  <span className="text-[10px] font-bold uppercase tracking-wider text-slate-400 bg-slate-100 px-1.5 py-0.5 rounded-md">
                    {log.tag}
                  </span>
                  <span className="text-[10px] text-slate-300 tabular-nums">
                    {new Date(log.time).toLocaleTimeString()}
                  </span>
                </div>
                <p className={cn(
                  "text-slate-600 leading-relaxed break-words font-medium",
                  log.type === 'error' && "text-red-600",
                  log.type === 'warn' && "text-amber-700"
                )}>
                  {log.msg}
                </p>
              </div>
            </div>
          ))}
        </div>
      </ScrollArea>
    </div>
  )
}
