import {
  CheckCircleOutlined,
  CloseCircleOutlined,
  LoadingOutlined,
  MinusCircleOutlined,
} from '@ant-design/icons'
import { Drawer, Progress, Space, Tag, Typography } from 'antd'
import { fetchEventSource } from '@microsoft/fetch-event-source'
import { useEffect, useRef, useState } from 'react'
import { useAuthStore } from '../store/auth'

interface RackStatus {
  rack_name: string
  rack_host: string
  state: 'pending' | 'running' | 'done' | 'error'
  found: number
  ssh_ok: boolean
}

interface SlaveItem {
  rack_name: string
  ip: string
  found: number
}

interface InfraItem {
  type: 'mikrotik' | 'proxmox'
  ip: string
}

interface DevicePingItem {
  ip: string
  status: 'online' | 'offline'
  ping_ms?: number | null
  phase?: string
}

type PhaseState = 'idle' | 'running' | 'done'

interface Props {
  open: boolean
  onClose: () => void
  objectName: string
  taskId: string | null
  onComplete?: () => void
}

export function DiscoveryDrawer({ open, onClose, objectName, taskId, onComplete }: Props) {
  const accessToken = useAuthStore((s) => s.accessToken)
  const [phase, setPhase] = useState<'connecting' | 'racks' | 'slaves' | 'infra' | 'done'>('connecting')
  const [currentAction, setCurrentAction] = useState<string | null>(null)
  const [racks, setRacks] = useState<RackStatus[]>([])
  const [current, setCurrent] = useState(0)
  const [total, setTotal] = useState(0)
  const [slaves, setSlaves] = useState<SlaveItem[]>([])
  const [slavesPhase, setSlavesPhase] = useState<PhaseState>('idle')
  const [mikrotikPhase, setMikrotikPhase] = useState<PhaseState>('idle')
  const [proxmoxPhase, setProxmoxPhase] = useState<PhaseState>('idle')
  const [infraFound, setInfraFound] = useState<InfraItem[]>([])
  const [devicePings, setDevicePings] = useState<DevicePingItem[]>([])
  const [result, setResult] = useState<{ created: number; updated: number; skipped: number; errors: string[] } | null>(null)
  const ctrlRef = useRef<AbortController | null>(null)

  useEffect(() => {
    if (!open || !taskId || !accessToken) return

    setPhase('connecting')
    setCurrentAction(null)
    setRacks([])
    setCurrent(0)
    setTotal(0)
    setSlaves([])
    setSlavesPhase('idle')
    setMikrotikPhase('idle')
    setProxmoxPhase('idle')
    setInfraFound([])
    setDevicePings([])
    setResult(null)

    const ctrl = new AbortController()
    ctrlRef.current = ctrl

    fetchEventSource(`/api/v1/events?task_id=${taskId}`, {
      headers: { Authorization: `Bearer ${accessToken}` },
      signal: ctrl.signal,
      onmessage(ev) {
        try {
          const data = JSON.parse(ev.data)

          if (ev.event === 'disc_action') {
            setCurrentAction(data.message)

          } else if (ev.event === 'disc_server') {
            setTotal(data.rack_count)
            setPhase('racks')

          } else if (ev.event === 'disc_rack_start') {
            setTotal(data.total)
            setCurrent(data.index)
            setRacks((prev) => {
              if (prev.find((r) => r.rack_name === data.rack_name)) {
                return prev.map((r) =>
                  r.rack_name === data.rack_name ? { ...r, state: 'running' } : r
                )
              }
              return [
                ...prev,
                { rack_name: data.rack_name, rack_host: data.rack_host, state: 'running', found: 0, ssh_ok: false },
              ]
            })

          } else if (ev.event === 'disc_rack_done') {
            setCurrent((c) => c + 1)
            setRacks((prev) =>
              prev.map((r) =>
                r.rack_name === data.rack_name
                  ? { ...r, state: data.ssh_ok ? 'done' : 'error', found: data.found ?? 0, ssh_ok: data.ssh_ok }
                  : r
              )
            )

          } else if (ev.event === 'disc_phase') {
            if (data.phase === 'slaves') {
              setPhase('slaves')
              setSlavesPhase('running')
            } else if (data.phase === 'mikrotik') {
              setPhase('infra')
              setSlavesPhase((s) => s === 'running' ? 'done' : s)
              setMikrotikPhase('running')
            } else if (data.phase === 'proxmox') {
              setMikrotikPhase((s) => s === 'running' ? 'done' : s)
              setProxmoxPhase('running')
            }

          } else if (ev.event === 'disc_slave_found') {
            setSlaves((prev) => [...prev, { rack_name: data.rack_name, ip: data.ip, found: data.found }])

          } else if (ev.event === 'disc_infra_found') {
            setInfraFound((prev) => [...prev, { type: data.type, ip: data.ip }])

          } else if (ev.event === 'disc_device_ping') {
            setCurrentAction((prev) => {
              if (prev) return prev
              const status = data.status === 'online' ? 'online' : 'offline'
              return `Проверка доступности ${data.ip}: ${status}`
            })
            setDevicePings((prev) => {
              const item = {
                ip: data.ip,
                status: data.status === 'online' ? 'online' : 'offline',
                ping_ms: data.ping_ms,
                phase: data.phase,
              } satisfies DevicePingItem
              const withoutCurrent = prev.filter((p) => p.ip !== item.ip)
              return [item, ...withoutCurrent].slice(0, 12)
            })

          } else if (ev.event === 'disc_done') {
            setResult({
              created: data.created ?? 0,
              updated: data.updated ?? 0,
              skipped: data.skipped ?? 0,
              errors: data.errors ?? [],
            })
            setSlavesPhase((s) => s === 'running' ? 'done' : s)
            setMikrotikPhase((s) => s === 'running' ? 'done' : s)
            setProxmoxPhase((s) => s === 'running' ? 'done' : s)
            setPhase('done')
            setCurrentAction(null)
            ctrl.abort()
            onComplete?.()
          }
        } catch {
          // ignore parse errors
        }
      },
      onerror(err) {
        ctrl.abort()
        throw err
      },
    })

    return () => ctrl.abort()
  }, [open, taskId, accessToken])

  const percent = total > 0 ? Math.round((current / total) * 100) : 0

  const rackIcon = (state: RackStatus['state']) => {
    if (state === 'running') return <LoadingOutlined style={{ color: '#1677ff' }} />
    if (state === 'done') return <CheckCircleOutlined style={{ color: '#52c41a' }} />
    if (state === 'error') return <CloseCircleOutlined style={{ color: '#ff4d4f' }} />
    return <MinusCircleOutlined style={{ color: '#d9d9d9' }} />
  }

  const phaseIcon = (state: PhaseState) => {
    if (state === 'running') return <LoadingOutlined style={{ color: '#1677ff', marginRight: 6 }} />
    if (state === 'done') return <CheckCircleOutlined style={{ color: '#52c41a', marginRight: 6 }} />
    return <MinusCircleOutlined style={{ color: '#d9d9d9', marginRight: 6 }} />
  }

  return (
    <Drawer
      title={`SSH Discovery — ${objectName}`}
      open={open}
      onClose={onClose}
      width={440}
      footer={null}
    >
      {/* Current action */}
      {(phase === 'connecting' || currentAction) && (
        <div style={{ marginBottom: 12, minHeight: 20 }}>
          {phase === 'connecting' && !currentAction ? (
            <Space>
              <LoadingOutlined />
              <Typography.Text type="secondary" style={{ fontSize: 12 }}>Запуск discovery...</Typography.Text>
            </Space>
          ) : currentAction ? (
            <Space>
              <LoadingOutlined style={{ fontSize: 11, color: '#8c8c8c' }} />
              <Typography.Text type="secondary" style={{ fontSize: 12 }}>{currentAction}</Typography.Text>
            </Space>
          ) : null}
        </div>
      )}

      {/* Rack progress bar */}
      {(phase === 'racks' || phase === 'slaves' || phase === 'infra' || phase === 'done') && (
        <div style={{ marginBottom: 16 }}>
          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
            Стойки: {Math.min(current, total)} / {total}
          </Typography.Text>
          <Progress
            percent={phase === 'done' || current >= total ? 100 : percent}
            status={phase === 'done' ? 'success' : 'active'}
            style={{ marginBottom: 0 }}
          />
        </div>
      )}

      {/* Rack list */}
      {racks.length > 0 && (
        <div style={{ marginBottom: 16 }}>
          {racks.map((r) => (
            <div
              key={r.rack_name}
              style={{ display: 'flex', alignItems: 'center', padding: '4px 0', gap: 8, borderBottom: '1px solid #f5f5f5' }}
            >
              {rackIcon(r.state)}
              <Typography.Text style={{ flex: 1, fontSize: 13 }}>{r.rack_name}</Typography.Text>
              <Typography.Text type="secondary" style={{ fontSize: 11 }}>{r.rack_host}</Typography.Text>
              {r.state === 'done' && (
                <Tag color="blue" style={{ marginLeft: 4, fontSize: 11 }}>{r.found} уст.</Tag>
              )}
              {r.state === 'error' && <Tag color="red" style={{ fontSize: 11 }}>SSH ошибка</Tag>}
            </div>
          ))}
        </div>
      )}

      {/* Ping status */}
      {devicePings.length > 0 && (
        <div style={{ marginBottom: 16, padding: '8px 0', borderTop: '1px solid #f0f0f0' }}>
          <Typography.Text type="secondary" style={{ display: 'block', fontSize: 12, marginBottom: 6 }}>
            Ping
          </Typography.Text>
          {devicePings.map((p) => (
            <div
              key={p.ip}
              style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '3px 0' }}
            >
              {p.status === 'online' ? (
                <CheckCircleOutlined style={{ color: '#52c41a', fontSize: 11 }} />
              ) : (
                <CloseCircleOutlined style={{ color: '#ff4d4f', fontSize: 11 }} />
              )}
              <Typography.Text style={{ flex: 1, fontSize: 12 }}>{p.ip}</Typography.Text>
              <Tag color={p.status === 'online' ? 'green' : 'red'} style={{ fontSize: 11 }}>
                {p.status}
              </Tag>
              {p.status === 'online' && p.ping_ms != null && (
                <Typography.Text type="secondary" style={{ fontSize: 11 }}>{p.ping_ms} ms</Typography.Text>
              )}
            </div>
          ))}
        </div>
      )}

      {/* Slave phase */}
      {slavesPhase !== 'idle' && (
        <div style={{ marginBottom: 12, padding: '8px 0', borderTop: '1px solid #f0f0f0' }}>
          <div style={{ display: 'flex', alignItems: 'center', marginBottom: slaves.length > 0 ? 6 : 0 }}>
            {phaseIcon(slavesPhase)}
            <Typography.Text style={{ fontSize: 13 }}>
              Слейв-стойки
              {slaves.length > 0 && <Tag color="purple" style={{ marginLeft: 8 }}>{slaves.length} найдено</Tag>}
            </Typography.Text>
          </div>
          {slaves.map((s) => (
            <div key={s.rack_name} style={{ display: 'flex', alignItems: 'center', gap: 8, paddingLeft: 22, paddingBottom: 4 }}>
              <CheckCircleOutlined style={{ color: '#52c41a', fontSize: 11 }} />
              <Typography.Text style={{ fontSize: 12 }}>{s.rack_name}</Typography.Text>
              <Typography.Text type="secondary" style={{ fontSize: 11 }}>{s.ip}</Typography.Text>
              <Tag color="blue" style={{ fontSize: 11 }}>{s.found} уст.</Tag>
            </div>
          ))}
        </div>
      )}

      {/* MikroTik phase */}
      {mikrotikPhase !== 'idle' && (
        <div style={{ display: 'flex', alignItems: 'center', padding: '6px 0', borderTop: '1px solid #f0f0f0' }}>
          {phaseIcon(mikrotikPhase)}
          <Typography.Text style={{ fontSize: 13, flex: 1 }}>MikroTik (SSH_CLIENT)</Typography.Text>
          {infraFound.filter((i) => i.type === 'mikrotik').map((i) => (
            <Tag key={i.ip} color="orange" style={{ fontSize: 11 }}>{i.ip}</Tag>
          ))}
          {mikrotikPhase === 'done' && infraFound.filter((i) => i.type === 'mikrotik').length === 0 && (
            <Typography.Text type="secondary" style={{ fontSize: 11 }}>не найден</Typography.Text>
          )}
        </div>
      )}

      {/* Proxmox phase */}
      {proxmoxPhase !== 'idle' && (
        <div style={{ display: 'flex', alignItems: 'center', padding: '6px 0', borderTop: '1px solid #f0f0f0' }}>
          {phaseIcon(proxmoxPhase)}
          <Typography.Text style={{ fontSize: 13, flex: 1 }}>Proxmox (порт 8006)</Typography.Text>
          {infraFound.filter((i) => i.type === 'proxmox').map((i) => (
            <Tag key={i.ip} color="cyan" style={{ fontSize: 11 }}>{i.ip}</Tag>
          ))}
          {proxmoxPhase === 'done' && infraFound.filter((i) => i.type === 'proxmox').length === 0 && (
            <Typography.Text type="secondary" style={{ fontSize: 11 }}>не найдено</Typography.Text>
          )}
        </div>
      )}

      {/* Final result */}
      {phase === 'done' && result && (
        <div style={{ borderTop: '1px solid #f0f0f0', paddingTop: 12, marginTop: 8 }}>
          <Space wrap>
            <Tag color="green">+{result.created} добавлено</Tag>
            <Tag color="blue">{result.updated} обновлено</Tag>
            <Tag>{result.skipped} без изменений</Tag>
          </Space>
          {result.errors.length > 0 && (
            <div style={{ marginTop: 10 }}>
              {result.errors.map((e, i) => (
                <Typography.Text
                  key={i}
                  type="danger"
                  style={{ display: 'block', fontSize: 12, marginBottom: 4 }}
                >
                  ⚠ {e}
                </Typography.Text>
              ))}
            </div>
          )}
        </div>
      )}
    </Drawer>
  )
}
