import {
  CheckCircleOutlined,
  ClockCircleOutlined,
  DeleteOutlined,
  EditOutlined,
  EyeOutlined,
} from '@ant-design/icons'
import {
  Badge,
  Breadcrumb,
  Button,
  Card,
  Col,
  Descriptions,
  Popconfirm,
  Result,
  Row,
  Select,
  Space,
  Spin,
  Table,
  Tag,
  Tooltip,
  Typography,
  message,
} from 'antd'
import dayjs from 'dayjs'
import { useState } from 'react'
import { useNavigate, useParams } from 'react-router-dom'
import { useAlerts, useAcknowledgeAlert, useResolveAlert, type AlertItem } from '../api/alerts'
import { useDevice, useDeleteDevice, useObject } from '../api/objects'
import { useSnapshots, useSnapshotDiff } from '../api/snapshots'
import { useDeviceTasks, useTask, type Task } from '../api/tasks'
import { DeviceEditModal } from '../components/DeviceEditModal'
import { CategoryTag, DeviceStatusBadge, TaskStatusBadge } from '../components/StatusBadge'
import { useMonitorSSE } from '../hooks/useMonitorSSE'

const ALERT_STATUS_COLOR: Record<string, string> = {
  open: 'error',
  acknowledged: 'warning',
  resolved: 'success',
}

const ALERT_STATUS_LABEL: Record<string, string> = {
  open: 'Открыт',
  acknowledged: 'Подтверждён',
  resolved: 'Закрыт',
}

const LOCATION_LABEL: Record<string, string> = {
  server_room: 'Серверная',
  street: 'Улица',
}

// ─── Alerts tab ─────────────────────────────────────────────────────────────

function AlertsTab({ deviceId }: { deviceId: number }) {
  const [statusFilter, setStatusFilter] = useState<string | undefined>(undefined)
  const { data: alerts, isLoading } = useAlerts({ device_id: deviceId, status: statusFilter })
  const acknowledge = useAcknowledgeAlert()
  const resolve = useResolveAlert()

  const columns = [
    {
      title: 'Сообщение',
      dataIndex: 'message',
      key: 'message',
    },
    {
      title: 'Статус',
      dataIndex: 'status',
      key: 'status',
      width: 140,
      render: (s: string) => (
        <Badge status={ALERT_STATUS_COLOR[s] as any} text={ALERT_STATUS_LABEL[s] ?? s} />
      ),
    },
    {
      title: 'Создан',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 160,
      render: (v: string) => dayjs(v).format('DD.MM.YY HH:mm'),
    },
    {
      title: 'Подтверждён',
      dataIndex: 'acknowledged_by_username',
      key: 'ack',
      width: 140,
      render: (v: string | null, row: AlertItem) =>
        v ? (
          <Tooltip title={row.acknowledged_at ? dayjs(row.acknowledged_at).format('DD.MM.YY HH:mm') : ''}>
            <Typography.Text type="secondary">{v}</Typography.Text>
          </Tooltip>
        ) : '—',
    },
    {
      title: '',
      key: 'actions',
      width: 120,
      render: (_: unknown, row: AlertItem) => (
        <Space size={4}>
          {row.status === 'open' && (
            <Tooltip title="Подтвердить">
              <Button
                size="small"
                icon={<CheckCircleOutlined />}
                loading={acknowledge.isPending}
                onClick={() => acknowledge.mutateAsync(row.id).catch(() => message.error('Ошибка'))}
              />
            </Tooltip>
          )}
          {row.status !== 'resolved' && (
            <Tooltip title="Закрыть">
              <Button
                size="small"
                danger
                icon={<DeleteOutlined />}
                loading={resolve.isPending}
                onClick={() => resolve.mutateAsync(row.id).catch(() => message.error('Ошибка'))}
              />
            </Tooltip>
          )}
        </Space>
      ),
    },
  ]

  return (
    <>
      <div style={{ marginBottom: 12 }}>
        <Select
          placeholder="Все статусы"
          allowClear
          style={{ width: 180 }}
          value={statusFilter}
          onChange={setStatusFilter}
          options={[
            { value: 'open', label: 'Открытые' },
            { value: 'acknowledged', label: 'Подтверждённые' },
            { value: 'resolved', label: 'Закрытые' },
          ]}
        />
      </div>
      <Table
        dataSource={alerts ?? []}
        columns={columns}
        rowKey="id"
        loading={isLoading}
        size="small"
        pagination={{ pageSize: 20 }}
        locale={{ emptyText: 'Нет алертов' }}
      />
    </>
  )
}

// ─── Snapshots tab ───────────────────────────────────────────────────────────

function SnapshotsTab({ objId, deviceId }: { objId: number; deviceId: number }) {
  const { data: snapshots, isLoading } = useSnapshots(objId, { device_id: deviceId })
  const [selectedA, setSelectedA] = useState<number | null>(null)
  const [selectedB, setSelectedB] = useState<number | null>(null)
  const { data: diffData, isFetching: diffLoading } = useSnapshotDiff(objId, selectedA, selectedB)

  const snapshotOptions = (snapshots ?? []).map((s) => ({
    value: s.id,
    label: `${dayjs(s.created_at).format('DD.MM.YY HH:mm')} — ${s.sha256.slice(0, 8)}`,
  }))

  const columns = [
    {
      title: 'Дата',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 160,
      render: (v: string) => dayjs(v).format('DD.MM.YY HH:mm:ss'),
    },
    {
      title: 'SHA-256',
      dataIndex: 'sha256',
      key: 'sha256',
      render: (v: string) => (
        <Tooltip title={v}>
          <code>{v.slice(0, 12)}…</code>
        </Tooltip>
      ),
    },
    {
      title: 'Размер',
      dataIndex: 'size',
      key: 'size',
      width: 100,
      render: (v: number) => `${v} Б`,
    },
    {
      title: 'Метка',
      dataIndex: 'label',
      key: 'label',
      render: (v: string | null) => v ?? '—',
    },
  ]

  const renderDiff = (diff: string) => {
    if (!diff) return <Typography.Text type="secondary">Нет изменений</Typography.Text>
    return (
      <pre style={{ fontSize: 12, maxHeight: 500, overflow: 'auto', background: '#fafafa', padding: 12, border: '1px solid #e8e8e8', borderRadius: 6 }}>
        {diff.split('\n').map((line, i) => {
          let color = 'inherit'
          if (line.startsWith('+') && !line.startsWith('+++')) color = '#237804'
          else if (line.startsWith('-') && !line.startsWith('---')) color = '#a8071a'
          else if (line.startsWith('@@')) color = '#096dd9'
          return (
            <span key={i} style={{ color, display: 'block' }}>{line}</span>
          )
        })}
      </pre>
    )
  }

  return (
    <>
      <Table
        dataSource={snapshots ?? []}
        columns={columns}
        rowKey="id"
        loading={isLoading}
        size="small"
        pagination={{ pageSize: 20 }}
        locale={{ emptyText: 'Снапшоты не найдены' }}
        style={{ marginBottom: 24 }}
      />

      <Typography.Title level={5} style={{ marginBottom: 12 }}>Сравнить снапшоты</Typography.Title>
      <Space style={{ marginBottom: 16 }} wrap>
        <Select
          placeholder="Снапшот A (старый)"
          style={{ width: 280 }}
          options={snapshotOptions}
          value={selectedA}
          onChange={setSelectedA}
          allowClear
        />
        <Select
          placeholder="Снапшот B (новый)"
          style={{ width: 280 }}
          options={snapshotOptions}
          value={selectedB}
          onChange={setSelectedB}
          allowClear
        />
      </Space>

      {diffLoading && <Spin />}
      {diffData && !diffLoading && (
        diffData.is_identical
          ? <Typography.Text type="secondary">Снапшоты идентичны</Typography.Text>
          : renderDiff(diffData.diff)
      )}
    </>
  )
}

// ─── Tasks tab ───────────────────────────────────────────────────────────────

function TaskResultRow({ taskId, deviceId }: { taskId: string; deviceId: number }) {
  const { data: detail, isLoading } = useTask(taskId)
  const deviceResult = detail?.device_results.find((r) => r.device_id === deviceId)

  if (isLoading) return <Spin size="small" />
  if (!deviceResult) return <Typography.Text type="secondary">Нет данных</Typography.Text>

  return (
    <div style={{ padding: '8px 16px', background: '#fafafa', borderRadius: 4 }}>
      <Space size={16} style={{ marginBottom: 8 }}>
        <span><b>Статус:</b> {deviceResult.status}</span>
        {deviceResult.exit_code !== null && <span><b>Код:</b> {deviceResult.exit_code}</span>}
        {deviceResult.duration_ms !== null && <span><b>Время:</b> {deviceResult.duration_ms}мс</span>}
        {deviceResult.executed_at && (
          <span><b>Выполнено:</b> {dayjs(deviceResult.executed_at).format('DD.MM.YY HH:mm:ss')}</span>
        )}
      </Space>
      {deviceResult.stdout && (
        <pre style={{ fontSize: 11, maxHeight: 200, overflow: 'auto', background: '#fff', padding: 8, border: '1px solid #e8e8e8', borderRadius: 4, marginBottom: 4 }}>
          {deviceResult.stdout}
        </pre>
      )}
      {deviceResult.stderr && (
        <pre style={{ fontSize: 11, maxHeight: 100, overflow: 'auto', background: '#fff4f4', padding: 8, border: '1px solid #ffa39e', borderRadius: 4, color: '#a8071a' }}>
          {deviceResult.stderr}
        </pre>
      )}
      {deviceResult.data && Object.keys(deviceResult.data).length > 0 && (
        <pre style={{ fontSize: 11, maxHeight: 200, overflow: 'auto', background: '#f6ffed', padding: 8, border: '1px solid #b7eb8f', borderRadius: 4 }}>
          {JSON.stringify(deviceResult.data, null, 2)}
        </pre>
      )}
    </div>
  )
}

function TasksTab({ deviceId }: { deviceId: number }) {
  const navigate = useNavigate()
  const { data: tasks, isLoading } = useDeviceTasks(deviceId)

  const columns = [
    {
      title: 'Тип',
      dataIndex: 'type',
      key: 'type',
      render: (v: string) => <code style={{ fontSize: 12 }}>{v}</code>,
    },
    {
      title: 'Статус',
      dataIndex: 'status',
      key: 'status',
      width: 140,
      render: (v: string) => <TaskStatusBadge status={v} />,
    },
    {
      title: 'Цель',
      dataIndex: 'target_label',
      key: 'target_label',
      render: (v: string | null) => v ?? '—',
    },
    {
      title: 'Создана',
      dataIndex: 'created_at',
      key: 'created_at',
      width: 160,
      render: (v: string) => dayjs(v).format('DD.MM.YY HH:mm'),
    },
    {
      title: 'Завершена',
      dataIndex: 'finished_at',
      key: 'finished_at',
      width: 160,
      render: (v: string | null) => v ? dayjs(v).format('DD.MM.YY HH:mm') : '—',
    },
    {
      title: '',
      key: 'actions',
      width: 80,
      render: (_: unknown, row: Task) => (
        <Tooltip title="Открыть задачу">
          <Button
            size="small"
            icon={<EyeOutlined />}
            onClick={() => navigate(`/tasks/${row.id}`)}
          />
        </Tooltip>
      ),
    },
  ]

  return (
    <Table
      dataSource={tasks ?? []}
      columns={columns}
      rowKey="id"
      loading={isLoading}
      size="small"
      pagination={{ pageSize: 20 }}
      locale={{ emptyText: 'Задачи не найдены' }}
      expandable={{
        expandedRowRender: (row: Task) => (
          <TaskResultRow taskId={row.id} deviceId={deviceId} />
        ),
      }}
    />
  )
}

// ─── Main page ───────────────────────────────────────────────────────────────

export function DeviceDetailPage() {
  const { id: objIdStr, deviceId: deviceIdStr } = useParams<{ id: string; deviceId: string }>()
  const objId = Number(objIdStr)
  const deviceId = Number(deviceIdStr)
  const navigate = useNavigate()

  const { data: obj } = useObject(objId)
  const { data: device, isLoading } = useDevice(objId, deviceId)
  const deleteDevice = useDeleteDevice(objId)

  const [editOpen, setEditOpen] = useState(false)
  const [activeTab, setActiveTab] = useState('info')
  const [liveStatus, setLiveStatus] = useState<{ status: string; ping_ms: number | null } | null>(null)

  useMonitorSSE({
    onDeviceStatus: (ev) => {
      if (ev.device_id === deviceId) {
        setLiveStatus({ status: ev.status, ping_ms: ev.ping_ms })
      }
    },
  })

  const effectiveStatus = liveStatus?.status ?? device?.status ?? 'unknown'
  const effectivePing = liveStatus !== null ? liveStatus.ping_ms : (device?.last_ping_ms ?? null)

  const handleDelete = async () => {
    try {
      await deleteDevice.mutateAsync(deviceId)
      message.success('Устройство удалено')
      navigate(`/inventory/objects/${objId}`)
    } catch {
      message.error('Ошибка при удалении')
    }
  }

  if (isLoading) return <Spin style={{ display: 'block', marginTop: 48 }} />
  if (!device) return <Result status="404" title="Устройство не найдено" extra={<Button onClick={() => navigate(`/inventory/objects/${objId}`)}>К объекту</Button>} />

  const breadcrumbItems = [
    { title: <a onClick={() => navigate('/inventory/objects')}>Инвентарь</a> },
    ...(obj?.city ? [{ title: <a onClick={() => navigate('/inventory/objects')}>{obj.city}</a> }] : []),
    { title: <a onClick={() => navigate(`/inventory/objects/${objId}`)}>{obj?.name ?? `Объект #${objId}`}</a> },
    { title: device.ip },
  ]

  const tabItems = [
    {
      key: 'info',
      label: 'Основное',
      children: (
        <Row gutter={24}>
          <Col xs={24} lg={14}>
            <Descriptions bordered size="small" column={1} labelStyle={{ width: 180 }}>
              <Descriptions.Item label="IP"><code>{device.ip}</code></Descriptions.Item>
              <Descriptions.Item label="Hostname">{device.hostname ?? '—'}</Descriptions.Item>
              <Descriptions.Item label="MAC">{device.mac ?? '—'}</Descriptions.Item>
              <Descriptions.Item label="Производитель">{device.vendor ?? '—'}</Descriptions.Item>
              <Descriptions.Item label="Модель">{device.model ?? '—'}</Descriptions.Item>
              <Descriptions.Item label="Прошивка">{device.firmware_version ?? '—'}</Descriptions.Item>
              <Descriptions.Item label="Категория"><CategoryTag category={device.category} /></Descriptions.Item>
              <Descriptions.Item label="Роль">{device.role !== 'other' ? device.role : '—'}</Descriptions.Item>
              <Descriptions.Item label="Источник">
                <Typography.Text type="secondary">{device.source}</Typography.Text>
              </Descriptions.Item>
              {device.external_id && (
                <Descriptions.Item label="External ID">
                  <code>{device.external_id}</code>
                </Descriptions.Item>
              )}
            </Descriptions>

            <Descriptions bordered size="small" column={1} labelStyle={{ width: 180 }} style={{ marginTop: 16 }}>
              <Descriptions.Item label="Объект">
                <a onClick={() => navigate(`/inventory/objects/${objId}`)}>{obj?.name ?? `#${objId}`}</a>
              </Descriptions.Item>
              <Descriptions.Item label="Стойка">
                {device.rack_name ? <Tag color="blue">{device.rack_name}{device.rack_type ? ` ${device.rack_type}` : ''}</Tag> : '—'}
              </Descriptions.Item>
              <Descriptions.Item label="Локация">
                {device.location ? (LOCATION_LABEL[device.location] ?? device.location) : '—'}
              </Descriptions.Item>
            </Descriptions>

            <Descriptions bordered size="small" column={1} labelStyle={{ width: 180 }} style={{ marginTop: 16 }}>
              <Descriptions.Item label="Статус"><DeviceStatusBadge status={effectiveStatus} /></Descriptions.Item>
              <Descriptions.Item label="Последний ping">
                {device.last_seen ? (
                  <Tooltip title={dayjs(device.last_seen).format('DD.MM.YYYY HH:mm:ss')}>
                    <Space size={4}>
                      <ClockCircleOutlined style={{ color: '#999' }} />
                      <span>{effectivePing !== null ? `${effectivePing}мс` : '—'}</span>
                    </Space>
                  </Tooltip>
                ) : '—'}
              </Descriptions.Item>
              <Descriptions.Item label="Мониторинг">
                {device.monitor_enabled
                  ? <Tag color="green">Включён</Tag>
                  : <Tag>Выключен</Tag>}
              </Descriptions.Item>
            </Descriptions>

            {(device.ssh_user_override || device.ssh_port_override) && (
              <Descriptions bordered size="small" column={1} labelStyle={{ width: 180 }} style={{ marginTop: 16 }}>
                {device.ssh_user_override && (
                  <Descriptions.Item label="SSH логин (override)">{device.ssh_user_override}</Descriptions.Item>
                )}
                {device.ssh_port_override && (
                  <Descriptions.Item label="SSH порт (override)">{device.ssh_port_override}</Descriptions.Item>
                )}
              </Descriptions>
            )}

            {device.notes && (
              <Card size="small" title="Заметки" style={{ marginTop: 16 }}>
                <Typography.Text>{device.notes}</Typography.Text>
              </Card>
            )}

            <Descriptions bordered size="small" column={2} style={{ marginTop: 16 }}>
              <Descriptions.Item label="Создано">
                {dayjs(device.created_at).format('DD.MM.YYYY HH:mm')}
              </Descriptions.Item>
              <Descriptions.Item label="Обновлено">
                {dayjs(device.updated_at).format('DD.MM.YYYY HH:mm')}
              </Descriptions.Item>
            </Descriptions>
          </Col>

          <Col xs={24} lg={10}>
            {device.capabilities.length > 0 && (
              <Card size="small" title="Возможности" style={{ marginBottom: 16 }}>
                <Space wrap>
                  {device.capabilities.map((c) => <Tag key={c}>{c}</Tag>)}
                </Space>
              </Card>
            )}

            {device.device_meta && Object.keys(device.device_meta).length > 0 && (
              <Card size="small" title="Метаданные устройства" style={{ marginBottom: 16 }}>
                <pre style={{ fontSize: 11, margin: 0, maxHeight: 300, overflow: 'auto' }}>
                  {JSON.stringify(device.device_meta, null, 2)}
                </pre>
              </Card>
            )}

            {device.connection_params && Object.keys(device.connection_params).length > 0 && (
              <Card size="small" title="Параметры подключения">
                <pre style={{ fontSize: 11, margin: 0, maxHeight: 300, overflow: 'auto' }}>
                  {JSON.stringify(device.connection_params, null, 2)}
                </pre>
              </Card>
            )}
          </Col>
        </Row>
      ),
    },
    {
      key: 'alerts',
      label: 'Алерты',
      children: <AlertsTab deviceId={deviceId} />,
    },
    {
      key: 'snapshots',
      label: 'Снапшоты',
      children: <SnapshotsTab objId={objId} deviceId={deviceId} />,
    },
    {
      key: 'tasks',
      label: 'История задач',
      children: <TasksTab deviceId={deviceId} />,
    },
  ]

  return (
    <div>
      <Breadcrumb style={{ marginBottom: 16 }} items={breadcrumbItems} />

      <Card style={{ marginBottom: 16 }}>
        <Row justify="space-between" align="top">
          <Col>
            <Space align="baseline" size={12}>
              <Typography.Title level={3} style={{ margin: 0 }}>
                <code>{device.ip}</code>
              </Typography.Title>
              <DeviceStatusBadge status={effectiveStatus} />
              {effectivePing !== null && (
                <Typography.Text type="secondary">{effectivePing}мс</Typography.Text>
              )}
            </Space>
            {device.hostname && (
              <div>
                <Typography.Text type="secondary" style={{ fontSize: 14 }}>{device.hostname}</Typography.Text>
              </div>
            )}
            <Space style={{ marginTop: 8 }} wrap>
              <CategoryTag category={device.category} />
              {device.role && device.role !== 'other' && <Tag>{device.role}</Tag>}
              {device.rack_name && <Tag color="blue">{device.rack_name}</Tag>}
              {device.vendor && <Tag color="default">{device.vendor}</Tag>}
              {device.model && <Typography.Text type="secondary" style={{ fontSize: 13 }}>{device.model}</Typography.Text>}
              {device.capabilities.map((c) => (
                <Tag key={c} color="geekblue" style={{ fontSize: 11 }}>{c}</Tag>
              ))}
            </Space>
          </Col>
          <Col>
            <Space>
              <Button icon={<EditOutlined />} onClick={() => setEditOpen(true)}>
                Редактировать
              </Button>
              <Popconfirm
                title="Удалить устройство?"
                description="Это действие необратимо."
                okText="Удалить"
                cancelText="Отмена"
                okButtonProps={{ danger: true }}
                onConfirm={handleDelete}
              >
                <Button danger icon={<DeleteOutlined />} loading={deleteDevice.isPending}>
                  Удалить
                </Button>
              </Popconfirm>
            </Space>
          </Col>
        </Row>
      </Card>

      <Card
        tabList={tabItems.map((t) => ({ key: t.key, tab: t.label }))}
        activeTabKey={activeTab}
        onTabChange={setActiveTab}
        bodyStyle={{ paddingTop: 16 }}
      >
        {tabItems.find((t) => t.key === activeTab)?.children}
      </Card>

      <DeviceEditModal
        open={editOpen}
        device={device}
        objId={objId}
        onClose={() => setEditOpen(false)}
      />
    </div>
  )
}
