import { useEffect, useMemo, useState } from "react"
import {
  Button,
  Card,
  Col,
  Descriptions,
  Popconfirm,
  Row,
  Space,
  Table,
  Tag,
  Tooltip,
  Typography,
} from "antd"
import {
  CloudServerOutlined,
  CopyOutlined,
  DesktopOutlined,
  KeyOutlined,
  PoweroffOutlined,
  ReloadOutlined,
  ThunderboltOutlined,
  WarningOutlined,
} from "@ant-design/icons"
import { osLogo } from "../../utils/osLogo"
import {
  listInstanceNatAcl,
  type InstanceNatAclList,
  type ServerDetail,
  type UpstreamDisk,
  type UpstreamTask,
} from "../../api/servers"
import InfoMonitorTab from "./InfoMonitorTab"
import {
  copyText,
  formatCycle,
  formatDate,
  formatMemory,
  networkLabel,
  statusTag,
  TASK_STATUS,
  TASK_TYPE,
} from "./helpers"

const { Text } = Typography

type InfoTabProps = {
  server: ServerDetail
  tasks: UpstreamTask[]
  taskLoading: boolean
  actionLoading: string | null
  actionDisabled: boolean
  powerActionSupport: { on: boolean; reboot: boolean; shutdown: boolean; hardoff: boolean } | null
  effectivePower: string | null
  onPowerOn: () => void
  onReboot: () => void
  onShutdown: () => void
  onHardShutdown: () => void
  onPasswordModalOpen: () => void
  onPluginAction: (action: string, label: string) => void
  onRefreshTasks: () => void
  onShowMonitor: () => void
}

function toNumber(value: unknown): number | null {
  if (value === null || value === undefined || value === "") return null
  const n = Number(value)
  return Number.isFinite(n) ? n : null
}

function formatGb(value: unknown) {
  const n = toNumber(value)
  if (n === null) return null
  return `${n} GB`
}

function isSystemDisk(disk: UpstreamDisk) {
  return String(disk.type ?? "").toLowerCase() === "system" || String(disk.dev ?? "").toLowerCase() === "vda"
}

function diskDeviceLabel(disk: UpstreamDisk) {
  return disk.dev ? `（${disk.dev}）` : ""
}

function systemDiskLabel(server: ServerDetail) {
  const disks = Array.isArray(server.upstream?.disk) ? server.upstream.disk : []
  const disk = disks.find(isSystemDisk)
  const upstreamSize = disk ? formatGb(disk.size) : null
  if (upstreamSize) return `${upstreamSize}${diskDeviceLabel(disk!)}`
  return server.system_disk_size ? `${server.system_disk_size} GB` : "-"
}

function dataDiskLabel(server: ServerDetail) {
  const disks = Array.isArray(server.upstream?.disk) ? server.upstream.disk : []
  const dataDisks = disks.filter((disk) => !isSystemDisk(disk))
  const sizes = dataDisks
    .map((disk) => toNumber(disk.size))
    .filter((size): size is number => size !== null)

  if (sizes.length > 0) {
    if (sizes.length === 1) return `${sizes[0]} GB${diskDeviceLabel(dataDisks[0])}`
    const total = sizes.reduce((sum, size) => sum + size, 0)
    return `共 ${total} GB（${sizes.join(" + ")}，${sizes.length} 块）`
  }

  return server.data_disk_size ? `${server.data_disk_size} GB` : "无"
}

function protocolAllowsTcp(protocol: number | null | undefined) {
  return protocol == null || protocol === 1 || protocol === 3
}

function isWindowsServer(server: ServerDetail) {
  const text = `${server.os_name || ""} ${server.os_image || ""}`.toLowerCase()
  return text.includes("windows") || text.includes("win")
}

function resolveConnectionAddress(server: ServerDetail, natAcl: InstanceNatAclList | null) {
  if (server.main_ip) {
    const port = server.ssh_port || (isWindowsServer(server) ? 3389 : 22)
    return `${server.main_ip}:${port}`
  }

  const natHostIp = natAcl?.nat_host_ip
  if (!natHostIp) return null

  const items = natAcl.list || []
  const portRule = [22, 3389]
    .map((port) => items.find((item) => item.int_port === port && item.ext_port && protocolAllowsTcp(item.protocol)))
    .find(Boolean)

  return portRule?.ext_port ? `${natHostIp}:${portRule.ext_port}` : null
}

export default function InfoTab({
  server,
  tasks,
  taskLoading,
  actionLoading,
  actionDisabled,
  powerActionSupport,
  effectivePower,
  onPowerOn,
  onReboot,
  onShutdown,
  onHardShutdown,
  onPasswordModalOpen,
  onPluginAction,
  onRefreshTasks,
  onShowMonitor,
}: InfoTabProps) {
  const osName = server.os_name || (server.os_image?.includes("|") ? server.os_image.split("|").slice(1).join("|") : server.os_image) || "-"
  const systemDisk = systemDiskLabel(server)
  const dataDisk = dataDiskLabel(server)
  const [natAcl, setNatAcl] = useState<InstanceNatAclList | null>(null)
  const [natAclLoading, setNatAclLoading] = useState(false)
  const connectionAddress = useMemo(() => resolveConnectionAddress(server, natAcl), [server, natAcl])
  const canPowerOn = !actionDisabled && (powerActionSupport?.on ?? true)
  const canReboot = !actionDisabled && (powerActionSupport?.reboot ?? true)
  const canShutdown = !actionDisabled && (powerActionSupport?.shutdown ?? true)
  const canHardShutdown = !actionDisabled && (powerActionSupport?.hardoff ?? true)
  const unsupportedTitle = "上游未开放该操作"

  useEffect(() => {
    if (server.main_ip || !server.upstream_id) {
      setNatAcl(null)
      setNatAclLoading(false)
      return
    }

    let cancelled = false
    setNatAclLoading(true)
    listInstanceNatAcl(server.id, {
      list_type: "all",
      per_page: 100,
      orderby: "int_port",
      sort: "asc",
    }).then((res) => {
      if (!cancelled) setNatAcl(res.data.data ?? null)
    }).catch(() => {
      if (!cancelled) setNatAcl(null)
    }).finally(() => {
      if (!cancelled) setNatAclLoading(false)
    })

    return () => {
      cancelled = true
    }
  }, [server.id, server.main_ip, server.upstream_id])

  return (
    <Space direction="vertical" size={16} style={{ width: "100%" }}>
      <Card variant="outlined" styles={{ body: { padding: 20 } }}>
        <Row gutter={[20, 20]} align="middle">
          <Col xs={24} md={10}>
            <Space size={14}>
              <div style={{ width: 54, height: 54, borderRadius: 12, border: "1px solid #f0f0f0", display: "flex", alignItems: "center", justifyContent: "center", background: "#fafafa" }}>
                <img src={osLogo(server.os_image)} alt="" style={{ width: 34, height: 34, objectFit: "contain" }} />
              </div>
              <Space direction="vertical" size={4}>
                <Space wrap>{statusTag(server.status, effectivePower)}</Space>
                <Text type="secondary">{osName}</Text>
              </Space>
            </Space>
          </Col>
          <Col xs={24} md={14}>
            <Row gutter={[12, 12]}>
              <Col xs={12} lg={6}><InfoTile label="网络" value={networkLabel(server)} copyable={!!server.main_ip} /></Col>
              <Col xs={12} lg={6}><InfoTile label="CPU" value={server.cpu ? `${server.cpu} 核` : "-"} /></Col>
              <Col xs={12} lg={6}><InfoTile label="内存" value={formatMemory(server.memory)} /></Col>
              <Col xs={12} lg={6}><InfoTile label="到期时间" value={formatDate(server.expires_at)} /></Col>
            </Row>
          </Col>
        </Row>
      </Card>

      <Card variant="outlined" title={<Space><ThunderboltOutlined /> 实例操作</Space>}>
        <Space wrap>
          <Tooltip title={!canPowerOn && powerActionSupport ? unsupportedTitle : undefined}>
          <Button type="primary" icon={<PoweroffOutlined />} loading={actionLoading === "on"} disabled={!canPowerOn} onClick={onPowerOn}>
            开机
          </Button>
          </Tooltip>
          <Popconfirm title="确认重启实例？" okText="重启" cancelText="取消" disabled={!canReboot} onConfirm={onReboot}>
            <Tooltip title={!canReboot && powerActionSupport ? unsupportedTitle : undefined}>
            <Button icon={<ReloadOutlined />} loading={actionLoading === "reboot"} disabled={!canReboot}>重启</Button>
            </Tooltip>
          </Popconfirm>
          <Popconfirm title="确认关机实例？" okText="关机" cancelText="取消" disabled={!canShutdown} onConfirm={onShutdown}>
            <Tooltip title={!canShutdown && powerActionSupport ? unsupportedTitle : undefined}>
            <Button danger icon={<PoweroffOutlined />} loading={actionLoading === "shutdown"} disabled={!canShutdown}>关机</Button>
            </Tooltip>
          </Popconfirm>
          <Popconfirm title="强制关机可能造成数据损坏，确认继续？" okText="强制关机" cancelText="取消" disabled={!canHardShutdown} onConfirm={onHardShutdown}>
            <Tooltip title={!canHardShutdown && powerActionSupport ? unsupportedTitle : undefined}>
            <Button danger icon={<WarningOutlined />} loading={actionLoading === "hardoff"} disabled={!canHardShutdown}>强制关机</Button>
            </Tooltip>
          </Popconfirm>
          <Button icon={<KeyOutlined />} loading={actionLoading === "password"} disabled={actionDisabled} onClick={onPasswordModalOpen}>
            重置密码
          </Button>
          <Button type="primary" ghost icon={<DesktopOutlined />} disabled={!server.upstream_id} onClick={() => window.open(`/control/server/${server.id}/vnc`, "_blank", "noopener,noreferrer")}>
            VNC
          </Button>
          {(server.plugin_manage_actions ?? []).map((action) => {
            const button = (
              <Button
                key={action.key}
                danger={action.style === "danger"}
                type={action.style === "primary" ? "primary" : "default"}
                loading={actionLoading === `plugin:${action.key}`}
                disabled={server.status === "provisioning"}
                onClick={action.confirm ? undefined : () => onPluginAction(action.key, action.label)}
              >
                {action.label}
              </Button>
            )
            return action.confirm ? (
              <Popconfirm
                key={action.key}
                title={`确认执行 ${action.label}？`}
                okText="确认"
                cancelText="取消"
                onConfirm={() => onPluginAction(action.key, action.label)}
              >
                {button}
              </Popconfirm>
            ) : button
          })}
        </Space>
      </Card>

      <Row gutter={[16, 16]} align="stretch">
        <Col xs={24} xl={14}>
          <Card variant="outlined" title={<Space><CloudServerOutlined /> 基础信息</Space>}>
            <Descriptions column={1} labelStyle={{ width: 120 }}>
              <Descriptions.Item label="实例 ID">#{server.id}</Descriptions.Item>
              <Descriptions.Item label="产品">{server.product_name}</Descriptions.Item>
              <Descriptions.Item label="线路">{server.product_group_name || "-"}</Descriptions.Item>
              <Descriptions.Item label="系统">{osName}</Descriptions.Item>
              <Descriptions.Item label="连接地址">
                {connectionAddress ? (
                  <Space>
                    <Text code>{connectionAddress}</Text>
                    <Button size="small" icon={<CopyOutlined />} onClick={() => copyText(connectionAddress, "连接地址")}>复制</Button>
                  </Space>
                ) : natAclLoading ? (
                  <Text type="secondary">加载中</Text>
                ) : "-"}
              </Descriptions.Item>
              <Descriptions.Item label="SSH 端口">{server.ssh_port ?? "-"}</Descriptions.Item>
              <Descriptions.Item label="系统盘">{systemDisk}</Descriptions.Item>
              <Descriptions.Item label="数据盘">{dataDisk}</Descriptions.Item>
              <Descriptions.Item label="入/出带宽">{server.in_bw ?? "-"} / {server.out_bw ?? "-"} Mbps</Descriptions.Item>
              <Descriptions.Item label="计费周期">
                <Tag color="blue" style={{ marginInlineEnd: 0 }}>{formatCycle(server.cycle)}</Tag>
              </Descriptions.Item>
              <Descriptions.Item label="Root 密码">
                {server.root_password ? (
                  <Space>
                    <Text code>********</Text>
                    <Button size="small" icon={<CopyOutlined />} onClick={() => copyText(server.root_password, "Root 密码")}>复制</Button>
                  </Space>
                ) : "-"}
              </Descriptions.Item>
            </Descriptions>
          </Card>
        </Col>
        <Col xs={24} xl={10}>
          <InfoMonitorTab server={server} mode="summary" onShowMore={onShowMonitor} />
        </Col>
      </Row>

      <Card
        variant="outlined"
        title={<Space><ReloadOutlined /> 任务记录</Space>}
        extra={<Button size="small" loading={taskLoading} onClick={onRefreshTasks}>刷新任务</Button>}
      >
        <Table
          rowKey={(record) => `${record.id}-${record.create_time}`}
          loading={taskLoading}
          dataSource={tasks}
          pagination={{ pageSize: 6, showSizeChanger: false }}
          columns={[
            { title: "任务", dataIndex: "type", render: (value: string) => TASK_TYPE[value] ?? value },
            {
              title: "状态",
              dataIndex: "status",
              render: (value: number) => {
                const meta = TASK_STATUS[value] ?? { label: String(value), color: "default" }
                return <Tag color={meta.color}>{meta.label}</Tag>
              },
            },
            { title: "进度", dataIndex: "progress", render: (value: number) => `${value ?? 0}%` },
            { title: "消息", dataIndex: "msg", render: (value: string) => value || "-" },
            { title: "创建时间", dataIndex: "create_time", render: (value: string) => value || "-" },
          ]}
        />
      </Card>
    </Space>
  )
}

function InfoTile({
  label,
  value,
  copyable = false,
}: {
  label: string
  value: string
  copyable?: boolean
}) {
  return (
    <Card size="small" variant="outlined" styles={{ body: { padding: 12 } }}>
      <Text type="secondary" style={{ fontSize: 12 }}>{label}</Text>
      <div style={{ marginTop: 6, display: "flex", alignItems: "center", gap: 6 }}>
        <Text strong ellipsis>{value}</Text>
        {copyable && (
          <Tooltip title="复制">
            <Button size="small" type="text" icon={<CopyOutlined />} onClick={() => copyText(value, label)} />
          </Tooltip>
        )}
      </div>
    </Card>
  )
}
