import { useEffect, useState } from "react"
import {
  Alert,
  Button,
  Card,
  Col,
  Descriptions,
  Empty,
  Form,
  InputNumber,
  Modal,
  Popconfirm,
  Row,
  Slider,
  Space,
  Statistic,
  Table,
  Tag,
  Typography,
  type TableColumnsType,
} from "antd"
import {
  CloudServerOutlined,
  DatabaseOutlined,
  HddOutlined,
  PayCircleOutlined,
  PlusOutlined,
} from "@ant-design/icons"
import {
  addDisk,
  deleteDisk,
  detachDisk,
  mountDisk,
  quoteDisk,
  quoteResizeDisk,
  resizeDisk,
  type DiskQuoteResult,
  type ServerConfigField,
  type ServerDetail,
  type UpstreamDisk,
} from "../../api/servers"
import { toast } from "../../utils/toast"
import { formatCycle, formatMoney, isZjmfFinanceServer, UNSUPPORTED_OPERATION_MESSAGE } from "./helpers"

const { Text } = Typography

interface Props {
  server: ServerDetail
  onRefresh?: () => void
  onTaskSubmitted?: () => void
}

interface DiskFormValues {
  size: number
}

type DiskModalMode = "create" | "resize"

type DiskRow = UpstreamDisk & {
  key: string
  inherited_delete_with_host?: number | string | null
  inherited_create_with_host?: number | string | null
}

const DISK_TYPE_META: Record<string, { label: string; color: string }> = {
  system: { label: "系统盘", color: "blue" },
  data: { label: "数据盘", color: "purple" },
}

const DISK_STATUS_META: Record<string, { label: string; color: string }> = {
  "0": { label: "未挂载", color: "default" },
  "1": { label: "已挂载", color: "success" },
  "2": { label: "挂载中", color: "processing" },
}

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 formatSizeGb(value: unknown) {
  const n = toNumber(value)
  return n === null ? "-" : `${n} GB`
}

function formatBytes(value: unknown) {
  const n = toNumber(value)
  if (n === null) return "-"
  if (n < 1024) return `${n} B`
  const units = ["KB", "MB", "GB", "TB"]
  let current = n / 1024
  let index = 0
  while (current >= 1024 && index < units.length - 1) {
    current /= 1024
    index += 1
  }
  return `${current.toFixed(current >= 10 ? 1 : 2)} ${units[index]}`
}

function formatNullable(value: unknown) {
  if (value === null || value === undefined || value === "") return "-"
  return String(value)
}

function formatLimit(value: unknown, unit = "") {
  const n = toNumber(value)
  if (n === null) return "-"
  if (n === 0) return "无限制"
  return `${n}${unit}`
}

function formatFlag(value: unknown) {
  const text = String(value ?? "")
  if (text === "1" || text.toLowerCase() === "true") return <Tag color="success">是</Tag>
  if (text === "0" || text.toLowerCase() === "false") return <Tag>否</Tag>
  return <Text type="secondary">-</Text>
}

function formatDate(value: unknown) {
  if (!value) return "-"
  const date = new Date(String(value).replace(" ", "T"))
  if (Number.isNaN(date.getTime())) return String(value)
  return date.toLocaleString("zh-CN", { hour12: false })
}

function diskTypeTag(type: unknown) {
  const key = String(type ?? "")
  const meta = DISK_TYPE_META[key] ?? { label: key || "未知", color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function diskStatusTag(status: unknown) {
  const key = String(status ?? "")
  const meta = DISK_STATUS_META[key] ?? { label: key || "未知", color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function limitPair(read: unknown, write: unknown, unit: string) {
  const r = formatLimit(read, unit)
  const w = formatLimit(write, unit)
  if (r === "-" && w === "-") return "-"
  return `读 ${r} / 写 ${w}`
}

function findConfig(fields: ServerConfigField[] | undefined, key: string): ServerConfigField | undefined {
  return fields?.find((field) => field.def.split("|")[0].trim() === key)
}

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

function nextResizeSize(currentSize: number, minSize: number, maxSize: number, step: number) {
  const safeStep = Math.max(1, step || 1)
  let next = currentSize + safeStep
  if (safeStep > 0) {
    next = minSize + Math.ceil((next - minSize) / safeStep) * safeStep
  }
  return Math.min(maxSize, Math.max(currentSize + 1, minSize, next))
}

export default function DiskTab({ server, onRefresh, onTaskSubmitted }: Props) {
  const [form] = Form.useForm<DiskFormValues>()
  const [modalMode, setModalMode] = useState<DiskModalMode | null>(null)
  const [targetDisk, setTargetDisk] = useState<DiskRow | null>(null)
  const [submitting, setSubmitting] = useState(false)
  const [quote, setQuote] = useState<DiskQuoteResult | null>(null)
  const [quoteLoading, setQuoteLoading] = useState(false)
  const [quoteError, setQuoteError] = useState("")
  const [diskActionLoading, setDiskActionLoading] = useState<string | null>(null)
  const upstream = server.upstream ?? {}
  const disks: DiskRow[] = Array.isArray(upstream.disk)
    ? upstream.disk.map((disk, index) => ({
      ...disk,
      key: String(disk.id ?? disk.name ?? disk.dev ?? index),
      inherited_delete_with_host: disk.delete_with_host ?? upstream.delete_with_host,
      inherited_create_with_host: disk.create_with_host ?? upstream.create_with_host,
    }))
    : []

  const totalSize = disks.reduce((sum, disk) => sum + (toNumber(disk.size) ?? 0), 0)
  const dataDiskCount = disks.filter((disk) => disk.type === "data").length
  const mountedCount = disks.filter((disk) => String(disk.status ?? "") === "1").length
  const baseRenewAmount = toNumber(server.unit_price) ?? 0
  const effectiveRenewAmount = toNumber(server.next_renew_amount) ?? baseRenewAmount
  const diskRenewAmount = Math.max(0, effectiveRenewAmount - baseRenewAmount)
  const diskConfig = findConfig(server.provision_config, "data_disk_size")
  const minDiskSize = diskConfig?.type === "slider" ? diskConfig.slider_min ?? 1 : 1
  const maxDiskSize = diskConfig?.type === "slider" ? diskConfig.slider_max ?? 1048576 : 1048576
  const diskStep = diskConfig?.type === "slider" ? diskConfig.slider_step ?? 1 : 1
  const modalOpen = modalMode !== null
  const currentResizeSize = toNumber(targetDisk?.size) ?? 0
  const minCreateSize = Math.max(1, minDiskSize)
  const minResizeSize = currentResizeSize > 0
    ? nextResizeSize(currentResizeSize, minCreateSize, maxDiskSize, diskStep)
    : minCreateSize
  const activeMinSize = modalMode === "resize" ? minResizeSize : minCreateSize
  const selectedSize = Form.useWatch("size", form) ?? activeMinSize
  const selectedSizeNumber = Number(selectedSize)
  const quoteReady = Boolean(
    quote && Number.isFinite(selectedSizeNumber) && quote.size === selectedSizeNumber && !quoteError,
  )
  const diskLimitReached = disks.length >= 3

  useEffect(() => {
    if (!modalOpen) return
    let cancelled = false
    const timer = window.setTimeout(() => {
      const size = Number(selectedSize)
      if (!Number.isFinite(size) || size <= 0) {
        setQuote(null)
        setQuoteError("请输入有效容量")
        setQuoteLoading(false)
        return
      }

      setQuoteLoading(true)
      setQuoteError("")
      const diskId = targetDisk?.id
      if (modalMode === "resize" && (diskId === null || diskId === undefined)) {
        setQuote(null)
        setQuoteError("磁盘 ID 异常")
        setQuoteLoading(false)
        return
      }
      const request = modalMode === "resize"
        ? quoteResizeDisk(server.id, diskId as number | string, { size })
        : quoteDisk(server.id, { size })
      request
        .then((res) => {
          if (cancelled) return
          setQuote(res.data.data ?? null)
        })
        .catch((error: unknown) => {
          if (cancelled) return
          const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
          setQuote(null)
          setQuoteError(detail || "费用计算失败")
        })
        .finally(() => {
          if (!cancelled) setQuoteLoading(false)
        })
    }, 300)

    return () => {
      cancelled = true
      window.clearTimeout(timer)
    }
  }, [modalMode, modalOpen, selectedSize, server.id, targetDisk?.id])

  const openCreateModal = () => {
    setModalMode("create")
    setTargetDisk(null)
    setQuote(null)
    setQuoteError("")
    setQuoteLoading(false)
    form.setFieldsValue({
      size: minCreateSize,
    })
  }

  const openResizeModal = (record: DiskRow) => {
    if (isSystemDisk(record)) {
      toast.error("系统盘不支持扩容")
      return
    }
    const currentSize = toNumber(record.size)
    if (currentSize === null) {
      toast.error("上游磁盘容量异常")
      return
    }
    if (record.id === null || record.id === undefined) {
      toast.error("磁盘 ID 异常")
      return
    }
    const nextSize = nextResizeSize(currentSize, minCreateSize, maxDiskSize, diskStep)
    if (nextSize <= currentSize) {
      toast.error("当前磁盘已达到可选最大容量")
      return
    }
    setModalMode("resize")
    setTargetDisk(record)
    setQuote(null)
    setQuoteError("")
    setQuoteLoading(false)
    form.setFieldsValue({ size: nextSize })
  }

  const closeCreateModal = () => {
    setModalMode(null)
    setTargetDisk(null)
    setQuote(null)
    setQuoteError("")
    setQuoteLoading(false)
  }

  const submitDiskAction = async () => {
    try {
      const values = await form.validateFields()
      setSubmitting(true)
      const res = modalMode === "resize" && targetDisk?.id !== null && targetDisk?.id !== undefined
        ? await resizeDisk(server.id, targetDisk.id, { size: values.size })
        : await addDisk(server.id, { size: values.size })
      const data = res.data.data
      const successText = modalMode === "resize" ? "扩容磁盘任务已下发" : "添加磁盘任务已下发"
      toast.success(data ? `${successText}，本次扣费 ${formatMoney(data.amount)}` : successText)
      closeCreateModal()
      onTaskSubmitted?.()
      onRefresh?.()
    } catch (error: unknown) {
      if ((error as { errorFields?: unknown[] })?.errorFields) return
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || (modalMode === "resize" ? "扩容磁盘失败" : "添加磁盘失败"))
    } finally {
      setSubmitting(false)
    }
  }

  const detachDiskAction = async (record: DiskRow) => {
    if (record.id === null || record.id === undefined) return
    const key = `detach-${record.key}`
    setDiskActionLoading(key)
    try {
      const res = await detachDisk(server.id, record.id)
      const data = res.data.data
      toast.success(data?.message || "卸载磁盘任务已下发")
      onTaskSubmitted?.()
      onRefresh?.()
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "卸载磁盘失败")
    } finally {
      setDiskActionLoading(null)
    }
  }

  const mountDiskAction = async (record: DiskRow) => {
    if (record.id === null || record.id === undefined) return
    const key = `mount-${record.key}`
    setDiskActionLoading(key)
    try {
      const res = await mountDisk(server.id, record.id)
      const data = res.data.data
      toast.success(data?.message || "挂载磁盘任务已下发")
      onTaskSubmitted?.()
      onRefresh?.()
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "挂载磁盘失败")
    } finally {
      setDiskActionLoading(null)
    }
  }

  const deleteDiskAction = async (record: DiskRow) => {
    if (record.id === null || record.id === undefined) return
    const key = `delete-${record.key}`
    setDiskActionLoading(key)
    try {
      await deleteDisk(server.id, record.id)
      toast.success("删除磁盘任务已下发，后续续费将不再计入该磁盘")
      onTaskSubmitted?.()
      onRefresh?.()
    } catch (error: unknown) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "删除磁盘失败")
    } finally {
      setDiskActionLoading(null)
    }
  }

  const columns: TableColumnsType<DiskRow> = [
    {
      title: "磁盘",
      dataIndex: "id",
      width: 180,
      render: (_value, record) => (
        <Space direction="vertical" size={0}>
          <Space size={8}>
            {diskTypeTag(record.type)}
            <Text strong>{formatNullable(record.name ?? record.id)}</Text>
          </Space>
          <Text type="secondary" style={{ fontSize: 12 }}>
            ID {formatNullable(record.id)}
          </Text>
        </Space>
      ),
    },
    {
      title: "容量",
      dataIndex: "size",
      width: 110,
      render: formatSizeGb,
    },
    {
      title: "挂载状态",
      dataIndex: "status",
      width: 110,
      render: diskStatusTag,
    },
    {
      title: "设备",
      dataIndex: "dev",
      width: 110,
      render: (value, record) => (
        <Space direction="vertical" size={0}>
          <Text>{formatNullable(value)}</Text>
          {record.dev === "vda" && <Text type="secondary" style={{ fontSize: 12 }}>启动盘</Text>}
        </Space>
      ),
    },
    {
      title: "存储",
      dataIndex: "store_name",
      width: 160,
      render: (value, record) => (
        <Space direction="vertical" size={0}>
          <Text>{formatNullable(value)}</Text>
          <Text type="secondary" style={{ fontSize: 12 }}>
            {formatNullable(record.store_type)} / {formatNullable(record.store_id)}
          </Text>
        </Space>
      ),
    },
    {
      title: "快照",
      dataIndex: "snap_num",
      width: 90,
      render: (value) => `${toNumber(value) ?? 0} 个`,
    },
    {
      title: "创建时间",
      dataIndex: "create_time",
      width: 180,
      render: formatDate,
    },
    {
      title: "操作",
      key: "action",
      width: 220,
      render: (_value, record) => {
        const currentSize = toNumber(record.size)
        const resizeDisabled = isSystemDisk(record)
          || currentSize === null
          || currentSize >= maxDiskSize
          || record.id === null
          || record.id === undefined
        const isMounted = String(record.status ?? "") === "1"
        const isUnmounted = String(record.status ?? "") === "0"
        const hasDiskId = record.id !== null && record.id !== undefined

        if (isSystemDisk(record)) return <Text type="secondary">-</Text>
        return (
          <Space size={4}>
            <Button type="link" size="small" disabled={resizeDisabled} onClick={() => openResizeModal(record)}>
              扩容
            </Button>
            {isMounted && (
              <Popconfirm
                title="卸载磁盘？"
                description="卸载不会退款，卸载完成后才能删除磁盘。"
                okText="确认卸载"
                cancelText="取消"
                onConfirm={() => detachDiskAction(record)}
              >
                <Button
                  type="link"
                  size="small"
                  loading={diskActionLoading === `detach-${record.key}`}
                  disabled={!hasDiskId || diskActionLoading !== null}
                >
                  卸载
                </Button>
              </Popconfirm>
            )}
            {isUnmounted && (
              <Popconfirm
                title="挂载磁盘？"
                description="将该数据盘重新挂载到当前实例，磁盘参数按后台配置自动下发。"
                okText="确认挂载"
                cancelText="取消"
                onConfirm={() => mountDiskAction(record)}
              >
                <Button
                  type="link"
                  size="small"
                  loading={diskActionLoading === `mount-${record.key}`}
                  disabled={!hasDiskId || diskActionLoading !== null}
                >
                  挂载
                </Button>
              </Popconfirm>
            )}
            <Popconfirm
              title="删除磁盘？"
              description="删除后不退款，后续续费不再计入该磁盘。"
              okText="确认删除"
              cancelText="取消"
              onConfirm={() => deleteDiskAction(record)}
              disabled={!isUnmounted || !hasDiskId}
            >
              <Button
                danger
                type="link"
                size="small"
                loading={diskActionLoading === `delete-${record.key}`}
                disabled={!isUnmounted || !hasDiskId || diskActionLoading !== null}
              >
                删除
              </Button>
            </Popconfirm>
          </Space>
        )
      },
    },
  ]

  if (isZjmfFinanceServer(server)) {
    return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description={UNSUPPORTED_OPERATION_MESSAGE} />
  }

  if (server.upstream_error) {
    return (
      <Alert
        type="warning"
        showIcon
        message="上游磁盘信息暂不可用"
        description={server.upstream_error}
      />
    )
  }

  if (!server.upstream_id) {
    return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="实例尚未开通，暂无磁盘信息" />
  }

  if (disks.length === 0) {
    return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="上游暂未返回磁盘信息" />
  }

  return (
    <Space direction="vertical" size={16} style={{ width: "100%" }}>
      <Row gutter={[16, 16]}>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined">
            <Statistic title="磁盘总数" value={disks.length} suffix="块" prefix={<HddOutlined />} />
          </Card>
        </Col>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined">
            <Statistic title="总容量" value={totalSize} suffix="GB" prefix={<DatabaseOutlined />} />
          </Card>
        </Col>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined">
            <Statistic
              title="已挂载 / 数据盘"
              value={`${mountedCount} / ${dataDiskCount}`}
              prefix={<CloudServerOutlined />}
            />
          </Card>
        </Col>
        <Col xs={24} sm={12} xl={6}>
          <Card variant="outlined">
            <Statistic
              title="磁盘续费"
              value={formatMoney(diskRenewAmount)}
              suffix={`/ ${formatCycle(server.cycle)}`}
              prefix={<PayCircleOutlined />}
            />
          </Card>
        </Col>
      </Row>

      <Table
        rowKey="key"
        columns={columns}
        dataSource={disks}
        pagination={false}
        scroll={{ x: 1180 }}
        expandable={{
          expandedRowRender: (record) => (
            <Descriptions
              size="small"
              column={{ xs: 1, sm: 2, xl: 3 }}
              bordered
              items={[
                { key: "remarks", label: "备注名称", children: formatNullable(record.remarks) },
                { key: "fs_type", label: "文件系统", children: formatNullable(record.fs_type) },
                { key: "io", label: "IO 模式", children: formatNullable(record.io) },
                { key: "driver", label: "驱动", children: formatNullable(record.driver) },
                { key: "cache", label: "缓存", children: formatNullable(record.cache) },
                { key: "real_size", label: "实际占用", children: formatBytes(record.real_size) },
                {
                  key: "bytes_limit",
                  label: "吞吐限制",
                  children: limitPair(record.read_bytes_sec, record.write_bytes_sec, " MB/s"),
                },
                {
                  key: "bytes_burst",
                  label: "吞吐突发",
                  children: limitPair(record.read_bytes_sec_max, record.write_bytes_sec_max, " MB"),
                },
                {
                  key: "iops_limit",
                  label: "IOPS 限制",
                  children: limitPair(record.read_iops_sec, record.write_iops_sec, " ops"),
                },
                {
                  key: "iops_burst",
                  label: "IOPS 突发",
                  children: limitPair(record.read_iops_sec_max, record.write_iops_sec_max, " ops"),
                },
                {
                  key: "hyperv_iops",
                  label: "Hyper-V IOPS",
                  children: `${formatLimit(record.iops_min)} - ${formatLimit(record.iops_max)}`,
                },
                {
                  key: "create_with_host",
                  label: "随实例创建",
                  children: formatFlag(record.inherited_create_with_host),
                },
                {
                  key: "delete_with_host",
                  label: "随实例删除",
                  children: formatFlag(record.inherited_delete_with_host),
                },
              ]}
            />
          ),
        }}
      />
      <Card variant="outlined" styles={{ body: { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 16 } }}>
        <Space direction="vertical" size={2}>
          <Text strong>弹性云盘</Text>
          <Text type="secondary">单个实例最多 3 块磁盘，添加后请等待上游任务完成。</Text>
        </Space>
        <Button type="primary" icon={<PlusOutlined />} disabled={diskLimitReached} onClick={openCreateModal}>
          添加磁盘
        </Button>
      </Card>

      <Modal
        title={modalMode === "resize" ? "扩容磁盘" : "添加弹性云盘"}
        open={modalOpen}
        onCancel={closeCreateModal}
        onOk={submitDiskAction}
        confirmLoading={submitting}
        okButtonProps={{ disabled: quoteLoading || !quoteReady }}
        okText="提交"
        cancelText="取消"
      >
        <Form form={form} layout="vertical" requiredMark="optional">
          <Form.Item
            label={modalMode === "resize" ? "目标容量" : "磁盘大小"}
            required
          >
            <Row gutter={12} align="middle">
              <Col flex="auto">
                <Form.Item name="size" noStyle rules={[{ required: true, message: "请选择磁盘大小" }]}>
                  <Slider
                    min={activeMinSize}
                    max={maxDiskSize}
                    step={diskStep}
                    tooltip={{ formatter: (value) => `${value} GB` }}
                  />
                </Form.Item>
              </Col>
              <Col flex="128px">
                <InputNumber
                  min={activeMinSize}
                  max={maxDiskSize}
                  step={diskStep}
                  value={Number.isFinite(selectedSizeNumber) ? selectedSizeNumber : activeMinSize}
                  onChange={(value) => {
                    if (value === null) return
                    form.setFieldsValue({ size: value })
                  }}
                  addonAfter="GB"
                  style={{ width: "100%" }}
                />
              </Col>
            </Row>
          </Form.Item>
          <Text type="secondary">
            {modalMode === "resize" && targetDisk
              ? `当前容量 ${formatSizeGb(targetDisk.size)}，可扩容至 ${activeMinSize} - ${maxDiskSize} GB`
              : `可选范围 ${minCreateSize} - ${maxDiskSize} GB`}
          </Text>
          <div style={{ marginTop: 16 }}>
            {quoteLoading || (modalOpen && !quoteError && !quoteReady) ? (
              <Text type="secondary">正在计算费用...</Text>
            ) : quoteError ? (
              <Text type="danger">{quoteError}</Text>
            ) : quoteReady && quote ? (
              <Descriptions
                size="small"
                bordered
                column={1}
                items={[
                  ...(modalMode === "resize"
                    ? [
                      {
                        key: "source_size",
                        label: "当前容量",
                        children: `${quote.source_size ?? currentResizeSize} GB`,
                      },
                      {
                        key: "target_size",
                        label: "扩容后",
                        children: `${quote.target_size ?? quote.size} GB`,
                      },
                      {
                        key: "delta_size",
                        label: "增加容量",
                        children: `${quote.delta_size ?? quote.billable_size} GB`,
                      },
                    ]
                    : []),
                  {
                    key: "current_charge",
                    label: "本次支付",
                    children: <Text strong>{formatMoney(quote.current_charge)}</Text>,
                  },
                  {
                    key: "recurring_amount",
                    label: "续费增加",
                    children: `${formatMoney(quote.recurring_amount)} / ${formatCycle(quote.cycle)}`,
                  },
                  {
                    key: "charged_until",
                    label: "覆盖到期",
                    children: formatDate(quote.charged_until),
                  },
                  {
                    key: "next_renew_amount",
                    label: "新增后续费",
                    children: `${formatMoney(quote.next_renew_amount)} / ${formatCycle(quote.cycle)}`,
                  },
                ]}
              />
            ) : null}
          </div>
          <div style={{ marginTop: 12 }}>
            <Text type="secondary">
              {modalMode === "resize"
                ? "只支持数据盘扩容。若实例处于开机状态，上游可能在修改后自动重启。"
                : "存储与磁盘参数将按后台产品配置自动下发，未配置时使用系统盘模板。"}
            </Text>
          </div>
        </Form>
      </Modal>
    </Space>
  )
}
