import { useCallback, useEffect, useMemo, useState } from "react"
import { useNavigate } from "react-router-dom"
import { Alert, Button, Card, Empty, Modal, Space, Statistic, Table, Tag, Tooltip, Typography } from "antd"
import {
  DeleteOutlined,
  ReloadOutlined,
  RollbackOutlined,
  ExclamationCircleOutlined,
  ShoppingCartOutlined,
  ApiOutlined,
  HddOutlined,
  ColumnHeightOutlined,
} from "@ant-design/icons"
import { listServiceOrders, unsubscribeOrder, type ServiceOrder } from "../../api/orders"
import { listInstanceActions, type UpstreamActionLog } from "../../api/upstreamActions"
import {
  deleteInstance,
  type ServerDetail,
} from "../../api/servers"
import { toast } from "../../utils/toast"
import { formatDate, formatMoney, isZjmfFinanceServer } from "./helpers"

const { Text } = Typography

// ── constants ──────────────────────────────────────────────────────

const REFUND_TYPE_META: Record<string, { label: string; color: string }> = {
  full: { label: "全额退订", color: "green" },
  prorated: { label: "实额退订", color: "blue" },
  no_refund: { label: "0元退订", color: "red" },
  unavailable: { label: "不可退订", color: "default" },
}

const ACTION_STATUS_META: Record<string, { label: string; color: string }> = {
  submitted: { label: "已下发", color: "processing" },
  running: { label: "执行中", color: "blue" },
  success: { label: "成功", color: "green" },
  failed: { label: "失败", color: "red" },
  no_task: { label: "已完成", color: "green" },
  manual_handled: { label: "人工已处理", color: "purple" },
  ignored: { label: "无需处理", color: "default" },
  superseded: { label: "已重试", color: "default" },
}

const RESOURCE_STATUS_META: Record<string, { label: string; color: string }> = {
  none: { label: "无资源动作", color: "default" },
  running: { label: "资源处理中", color: "processing" },
  failed: { label: "资源异常", color: "red" },
  finished: { label: "资源已处理", color: "green" },
  manual_handled: { label: "人工已处理", color: "purple" },
  ignored: { label: "无需处理", color: "default" },
}

const ACTION_TYPE_LABEL: Record<string, string> = {
  instance_delete: "强制删除实例",
  instance_suspend: "暂停实例",
  instance_unsuspend: "解除暂停",
  disk_detach: "卸载云盘",
  disk_delete: "删除云盘",
  disk_resize_rollback: "回退云盘容量",
  package_instance_rollback: "回退套餐配置",
  package_bandwidth_rollback: "回退带宽配置",
}

// ── helpers ────────────────────────────────────────────────────────

function snapshotInstanceId(item: unknown) {
  if (!item || typeof item !== "object") return null
  const value = (item as { instance_id?: unknown }).instance_id
  if (value === null || value === undefined || value === "") return null
  const n = Number(value)
  return Number.isFinite(n) ? n : null
}

function belongsToServer(order: ServiceOrder, serverId: number) {
  if (order.instances.some((item) => item.id === serverId)) return true
  return (order.items_snapshot || []).some((item) => snapshotInstanceId(item) === serverId)
}

function refundTypeTag(type: string) {
  const meta = REFUND_TYPE_META[type] ?? REFUND_TYPE_META.unavailable
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function actionStatusTag(status: string) {
  const meta = ACTION_STATUS_META[status] ?? { label: status, color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function resourceStatusTag(status: string) {
  const meta = RESOURCE_STATUS_META[status] ?? { label: status, color: "default" }
  return <Tag color={meta.color}>{meta.label}</Tag>
}

function latestAction(actions: UpstreamActionLog[]) {
  return [...actions].sort((a, b) => b.id - a.id)[0] ?? null
}

function resourceStatusFromAction(action: UpstreamActionLog | null) {
  if (!action) return "none"
  if (["submitted", "running"].includes(action.status)) return "running"
  if (action.status === "failed") return "failed"
  if (action.status === "manual_handled") return "manual_handled"
  if (action.status === "ignored") return "ignored"
  return "finished"
}

function resourceStatusFromOrder(order: ServiceOrder) {
  return order.refund?.resource_status || resourceStatusFromAction(latestAction(order.upstream_actions || []))
}

function errorDetail(error: unknown, fallback: string) {
  return (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail || fallback
}

function orderItemType(item: unknown): string {
  if (!item || typeof item !== "object") return "server_purchase"
  return String((item as { type?: string }).type || "server_purchase")
}

function isServerPurchase(items: unknown[]) {
  return items.some((item) => orderItemType(item) === "server_purchase")
}

function itemIcon(item: unknown) {
  const t = orderItemType(item)
  if (t === "package_upgrade") return <ApiOutlined />
  if (t === "disk_addon") return <HddOutlined />
  if (t === "disk_resize") return <ColumnHeightOutlined />
  return <ShoppingCartOutlined />
}

function itemColor(item: unknown) {
  const t = orderItemType(item)
  if (t === "package_upgrade") return "#1677ff"
  if (t === "disk_addon") return "#52c41a"
  if (t === "disk_resize") return "#fa8c16"
  return "#8c8c8c"
}

// An order is "resolved" if it's already been unsubscribed/refunded.
// Backend cascade skips these (only processes status==paid orders with no refund),
// so the frontend must exclude them from cascade validation/preview too.
function isResolved(order: ServiceOrder) {
  return order.status === "refunded" || order.status === "cancelled" || order.refund != null
}

// ── component ──────────────────────────────────────────────────────

interface RefundTabProps {
  server: ServerDetail
  onRefresh: () => void | Promise<void>
  onTaskSubmitted: () => void | Promise<void>
}

export default function RefundTab({ server, onRefresh, onTaskSubmitted }: RefundTabProps) {
  const navigate = useNavigate()
  const isFinanceServer = isZjmfFinanceServer(server)
  const [orders, setOrders] = useState<ServiceOrder[]>([])
  const [actions, setActions] = useState<UpstreamActionLog[]>([])
  const [loading, setLoading] = useState(false)
  const [actionsLoading, setActionsLoading] = useState(false)
  const [actionLoading, setActionLoading] = useState<string | null>(null)

  const loadOrders = useCallback(async () => {
    if (isFinanceServer) {
      setOrders([])
      return
    }
    setLoading(true)
    try {
      const res = await listServiceOrders()
      setOrders((res.data ?? []).filter((order) => belongsToServer(order, server.id)))
    } catch (error) {
      toast.error(errorDetail(error, "退订订单加载失败"))
    } finally {
      setLoading(false)
    }
  }, [isFinanceServer, server.id])

  const loadActions = useCallback(async () => {
    if (isFinanceServer) {
      setActions([])
      return
    }
    setActionsLoading(true)
    try {
      const res = await listInstanceActions(server.id, 80)
      setActions(res.data.data ?? [])
    } catch (error) {
      toast.error(errorDetail(error, "资源操作记录加载失败"))
    } finally {
      setActionsLoading(false)
    }
  }, [isFinanceServer, server.id])

  useEffect(() => {
    if (isFinanceServer) return
    void loadOrders()
    void loadActions()
  }, [isFinanceServer, loadActions, loadOrders])

  // Separate into purchase + related children + standalone
  const { purchaseOrder, childOrders, standaloneOrders } = useMemo(() => {
    const purchase = orders.find((o) => isServerPurchase(o.items_snapshot || []))
    const purchaseId = purchase?.id
    const children = purchase
      ? orders.filter((o) => {
          if (o.id === purchaseId) return false
          return (o.items_snapshot || []).some(
            (item: unknown) => snapshotInstanceId(item) === server.id,
          )
        })
      : []
    const standalone = orders.filter(
      (o) => !isServerPurchase(o.items_snapshot || []) && !children.includes(o),
    )
    // Sort children: upgrades first, then disks
    const typeRank: Record<string, number> = { package_upgrade: 0, disk_resize: 1, disk_addon: 2 }
    children.sort((a, b) => {
      const ta = a.items_snapshot?.[0] ? orderItemType(a.items_snapshot[0]) : ""
      const tb = b.items_snapshot?.[0] ? orderItemType(b.items_snapshot[0]) : ""
      return (typeRank[ta] ?? 99) - (typeRank[tb] ?? 99)
    })
    return { purchaseOrder: purchase, childOrders: children, standaloneOrders: standalone }
  }, [orders, server.id])

  const refundableOrders = useMemo(
    () => orders.filter((order) => order.refund_policy.action_allowed),
    [orders],
  )

  // Children that haven't been unsubscribed yet — these are what cascade will actually process.
  const pendingChildren = useMemo(
    () => childOrders.filter((o) => !isResolved(o)),
    [childOrders],
  )

  // Can cascade: purchase refundable + all *pending* children refundable
  const canCascadeUnsubscribe = useMemo(() => {
    if (!purchaseOrder || !purchaseOrder.refund_policy.action_allowed) return false
    if (pendingChildren.length === 0) return true
    return pendingChildren.every((o) => o.refund_policy.action_allowed)
  }, [purchaseOrder, pendingChildren])

  const cascadeTotalRefund = useMemo(() => {
    if (!purchaseOrder) return 0
    let total = purchaseOrder.refund_policy.refund_amount
    for (const child of pendingChildren) {
      total += child.refund_policy.refund_amount
    }
    return total
  }, [purchaseOrder, pendingChildren])

  // Merged, ordered list for the table: purchase first, then its children, then standalone
  const tableOrders = useMemo(() => {
    const result: ServiceOrder[] = []
    if (purchaseOrder) result.push(purchaseOrder)
    result.push(...childOrders)
    result.push(...standaloneOrders)
    return result
  }, [purchaseOrder, childOrders, standaloneOrders])

  const isPurchaseRow = (o: ServiceOrder) => purchaseOrder?.id === o.id
  const isChildRow = (o: ServiceOrder) => childOrders.some((c) => c.id === o.id)

  // ── cascade unsubscribe ─────────────────────────────────────────

  const confirmCascadeUnsubscribe = () => {
    if (!purchaseOrder || !canCascadeUnsubscribe) return

    const hasChildren = pendingChildren.length > 0
    const noRefund = cascadeTotalRefund === 0
    Modal.confirm({
      title: noRefund
        ? "确认退订并删除服务器？"
        : hasChildren
          ? "确认级联退订全部关联订单？"
          : "确认退订该订单？",
      icon: <ExclamationCircleOutlined />,
      okText: noRefund ? "确认删除服务器" : "确认退订",
      cancelText: "取消",
      okButtonProps: { danger: true },
      width: 520,
      content: (
        <Space orientation="vertical" size={12} style={{ width: "100%" }}>
          {noRefund && (
            <Alert
              type="error"
              showIcon
              title="本次退订不退款，但服务器将被永久删除"
              description="相关订单已 0 元退订（领取了消费积分），确认后实例及数据将被强制删除，无法恢复，请谨慎操作。"
            />
          )}
          <Card size="small" variant="outlined" style={{ background: "#fafafa" }}>
            <Space orientation="vertical" size={4}>
              <Text strong>
                {itemIcon({ type: "server_purchase" })}{" "}
                服务器：{purchaseOrder.content?.[0] || purchaseOrder.out_order_no}
              </Text>
              <Text type="secondary">退款：{formatMoney(purchaseOrder.refund_policy.refund_amount)}</Text>
            </Space>
          </Card>
          {pendingChildren.map((child) => (
            <Card key={child.id} size="small" variant="outlined" style={{ background: "#fafafa" }}>
              <Space orientation="vertical" size={4}>
                <Text strong>
                  <span style={{ color: itemColor(child.items_snapshot?.[0]) }}>
                    {itemIcon(child.items_snapshot?.[0])}{" "}
                  </span>
                  {child.content?.[0] || `订单 #${child.id}`}
                </Text>
                <Text type="secondary">退款：{formatMoney(child.refund_policy.refund_amount)}</Text>
              </Space>
            </Card>
          ))}
          {hasChildren && (
            <>
              <div style={{ borderTop: "1px solid #f0f0f0", paddingTop: 8 }}>
                <Text strong style={{ fontSize: 15 }}>
                  预计总退款：{formatMoney(cascadeTotalRefund)}
                </Text>
              </div>
              <Text type="danger">
                处理顺序：套餐升级回退 → 磁盘回退 → 实例删除。此操作不可恢复。
              </Text>
            </>
          )}
        </Space>
      ),
      onOk: async () => {
        setActionLoading("cascade-unsubscribe")
        try {
          const res = await unsubscribeOrder(purchaseOrder.id)
          const data = res.data
          const refunds = data?.refunds
          const refundCount = refunds?.length ?? 0
          const totalRefund = data?.total_refund ?? 0
          toast.success(
            `已退订 ${refundCount} 笔订单` +
              (totalRefund > 0 ? `，共退款 ${formatMoney(totalRefund)}` : ""),
          )
          await loadOrders()
          await loadActions()
          await onRefresh()
          await onTaskSubmitted()
        } catch (error) {
          toast.error(errorDetail(error, "退订失败"))
          throw error
        } finally {
          setActionLoading(null)
        }
      },
    })
  }

  // ── single (standalone) order unsubscribe ────────────────────────

  const confirmUnsubscribe = (record: ServiceOrder) => {
    const policy = record.refund_policy
    if (!policy.action_allowed) return

    Modal.confirm({
      title: "确认退订该订单？",
      okText: "确认退订",
      cancelText: "取消",
      okButtonProps: { danger: true },
      content: (
        <Space orientation="vertical" size={8}>
          <Text>订单：{record.out_order_no}</Text>
          <Text>
            退款金额：<Text strong>{formatMoney(policy.refund_amount)}</Text>
          </Text>
          <Text type="danger">此操作不可恢复。</Text>
        </Space>
      ),
      onOk: async () => {
        setActionLoading(`unsubscribe-${record.id}`)
        try {
          await unsubscribeOrder(record.id)
          toast.success("退订已处理")
          await loadOrders()
          await loadActions()
          await onRefresh()
          await onTaskSubmitted()
        } catch (error) {
          toast.error(errorDetail(error, "退订失败"))
          throw error
        } finally {
          setActionLoading(null)
        }
      },
    })
  }

  // ── delete ─────────────────────────────────────────────────────

  const confirmDeleteInstance = () => {
    Modal.confirm({
      title: "强制删除实例？",
      okText: "确认强制删除",
      cancelText: "取消",
      okButtonProps: { danger: true },
      content: (
        <Space orientation="vertical" size={8}>
          <Text>删除实例不会退款，也无法恢复。</Text>
          <Text type="danger">此操作不可撤销，请谨慎操作。</Text>
        </Space>
      ),
      onOk: async () => {
        setActionLoading("delete-instance")
        try {
          await deleteInstance(server.id)
          toast.success("删除实例任务已下发")
          await loadActions()
          await onRefresh()
          await onTaskSubmitted()
        } catch (error) {
          toast.error(errorDetail(error, "删除实例失败"))
          throw error
        } finally {
          setActionLoading(null)
        }
      },
    })
  }

  const openFinanceRefundTicket = () => {
    const subject = `实例 #${server.id} 退订协助`
    const content = [
      "<p>工单类型：对接产品退订/资源处理协助</p>",
      `<p>实例 ID：#${server.id}</p>`,
      `<p>产品：${server.product_name || "-"}</p>`,
      `<p>线路：${server.product_group_name || "-"}</p>`,
      `<p>主机名：${server.hostname || "-"}</p>`,
      `<p>当前到期：${formatDate(server.expires_at)}</p>`,
      "<p>申请原因/补充说明：</p>",
      "<p><br></p>",
      "<p>是否确认需要处理上游资源：</p>",
      "<p><br></p>",
    ].join("")
    const params = new URLSearchParams({
      department: "finance",
      department_code: "finance",
      priority: "normal",
      instance_id: String(server.id),
      subject,
      content,
    })
    navigate(`/tickets/create?${params.toString()}`)
  }

  // ── render ───────────────────────────────────────────────────────

  if (isFinanceServer) {
    return (
      <Card variant="outlined">
        <Empty
          image={Empty.PRESENTED_IMAGE_SIMPLE}
          description="该对接产品需要通过财务工单处理退订和资源操作"
        >
          <Button type="primary" onClick={openFinanceRefundTicket}>
            发起财务工单
          </Button>
        </Empty>
      </Card>
    )
  }

  return (
    <Space orientation="vertical" size={16} style={{ width: "100%" }}>
      <Alert
        type="warning"
        showIcon
        title="退订会同步处理上游资源"
        description="服务器退订会强制删除实例；新增磁盘退订会删除磁盘；磁盘扩容退订会回退到扩容前容量；套餐升级退订会回退原套餐配置。"
      />

      {/* ── Stats row ── */}
      <Space wrap>
        <Card variant="outlined">
          <Statistic title="相关订单" value={orders.length} suffix="笔" />
        </Card>
        <Card variant="outlined">
          <Statistic title="可退订" value={refundableOrders.length} suffix="笔" />
        </Card>
        {purchaseOrder && pendingChildren.length > 0 && (
          <Card variant="outlined">
            <Statistic title="级联总退款" value={formatMoney(cascadeTotalRefund)} />
          </Card>
        )}
        <Card variant="outlined">
          <Statistic title="到期时间" value={formatDate(server.expires_at)} />
        </Card>
      </Space>

      {/* ── Action buttons ── */}
      <Card title="实例操作" variant="outlined">
        <Space wrap>
          <Button
            icon={<ReloadOutlined />}
            loading={loading}
            onClick={() => void loadOrders()}
          >
            刷新退订订单
          </Button>
          <Button
            icon={<ReloadOutlined />}
            loading={actionsLoading}
            onClick={() => void loadActions()}
          >
            刷新操作进度
          </Button>
          <Button
            danger
            icon={<DeleteOutlined />}
            disabled={server.status === "terminated"}
            loading={actionLoading === "delete-instance"}
            onClick={confirmDeleteInstance}
          >
            强制删除实例
          </Button>
        </Space>
      </Card>

      {/* ── Resource action progress ── */}
      <Card title="资源操作进度" variant="outlined">
        <Table
          rowKey="id"
          size="small"
          loading={actionsLoading}
          dataSource={actions}
          pagination={{ pageSize: 6, showSizeChanger: false }}
          scroll={{ x: 980 }}
          columns={[
            {
              title: "动作",
              dataIndex: "action_type",
              width: 150,
              render: (value: string) => ACTION_TYPE_LABEL[value] ?? value,
            },
            {
              title: "状态",
              dataIndex: "status",
              width: 100,
              render: actionStatusTag,
            },
            {
              title: "Task ID",
              dataIndex: "upstream_task_id",
              width: 110,
              render: (value: number | null) => (value ? <Text code>{value}</Text> : "-"),
            },
            {
              title: "来源",
              dataIndex: "source",
              width: 100,
              render: (value: string) => <Tag>{value}</Tag>,
            },
            {
              title: "备注/错误",
              ellipsis: true,
              render: (_, record: UpstreamActionLog) =>
                record.error_message || record.remark || "-",
            },
            {
              title: "时间",
              dataIndex: "created_at",
              width: 165,
              render: (value: string | null) => (
                <Text type="secondary">{formatDate(value)}</Text>
              ),
            },
          ]}
          locale={{
            emptyText: (
              <Empty
                image={Empty.PRESENTED_IMAGE_SIMPLE}
                description="暂无资源操作记录"
              />
            ),
          }}
        />
      </Card>

      {/* ── Order table ── */}
      <Card
        title="退订订单"
        variant="outlined"
        extra={
          purchaseOrder && canCascadeUnsubscribe ? (
            <Button
              type="primary"
              danger
              icon={<RollbackOutlined />}
              loading={actionLoading === "cascade-unsubscribe"}
              onClick={confirmCascadeUnsubscribe}
            >
              一键退订全部
              {pendingChildren.length > 0 ? ` (${pendingChildren.length + 1}笔)` : ""}
            </Button>
          ) : null
        }
      >
        <Table
          rowKey="id"
          size="small"
          loading={loading}
          dataSource={tableOrders}
          pagination={false}
          scroll={{ x: 1100 }}
          locale={{
            emptyText: (
              <Empty
                image={Empty.PRESENTED_IMAGE_SIMPLE}
                description="暂无可关联的服务订单"
              />
            ),
          }}
          columns={[
            {
              title: "内容",
              dataIndex: "content",
              render: (_value, record) => {
                const child = isChildRow(record)
                const purchase = isPurchaseRow(record)
                const resolved = isResolved(record)
                return (
                  <Space size={6} style={{ paddingLeft: child ? 16 : 0 }}>
                    {child && <Text type="secondary">↳</Text>}
                    <span style={{ color: itemColor(record.items_snapshot?.[0]) }}>
                      {itemIcon(record.items_snapshot?.[0])}
                    </span>
                    <Text strong={purchase} delete={resolved} type={resolved ? "secondary" : undefined}>
                      {record.content?.[0] || `服务订单 #${record.id}`}
                    </Text>
                    {resolved && <Tag>已退订</Tag>}
                    {purchase && pendingChildren.length > 0 && (
                      <Tag color="blue" style={{ marginInlineStart: 0 }}>
                        含 {pendingChildren.length} 个关联
                      </Tag>
                    )}
                  </Space>
                )
              },
            },
            {
              title: "订单号",
              dataIndex: "out_order_no",
              width: 200,
              render: (value: string) => <Text code style={{ fontSize: 11 }}>{value}</Text>,
            },
            {
              title: "实付",
              dataIndex: "paid_amount",
              width: 100,
              align: "right",
              render: (value: number) => <Text>{formatMoney(value)}</Text>,
            },
            {
              title: "退订规则",
              dataIndex: "refund_policy",
              width: 200,
              render: (_value, record) => (
                <Space orientation="vertical" size={2}>
                  {refundTypeTag(record.refund_policy.refund_type)}
                  <Text type="secondary" style={{ fontSize: 12 }}>
                    {record.refund_policy.reason}
                  </Text>
                </Space>
              ),
            },
            {
              title: "预计退款",
              width: 110,
              align: "right",
              render: (_value, record) => (
                <Text strong style={{ color: "#cf1322" }}>
                  {formatMoney(record.refund_policy.refund_amount)}
                </Text>
              ),
            },
            {
              title: "资源进度",
              width: 150,
              render: (_value, record) => {
                const action = latestAction(record.upstream_actions || [])
                const resourceStatus = resourceStatusFromOrder(record)
                if (resourceStatus === "none" && !action) return <Text type="secondary">-</Text>
                return (
                  <Space orientation="vertical" size={2}>
                    {resourceStatusTag(resourceStatus)}
                    <Text type="secondary" style={{ fontSize: 12 }}>
                      {record.refund?.resource_error ||
                        (action ? ACTION_TYPE_LABEL[action.action_type] ?? action.action_type : "-")}
                    </Text>
                  </Space>
                )
              },
            },
            {
              title: "操作",
              key: "action",
              width: 120,
              fixed: "right",
              render: (_value, record) => {
                if (isPurchaseRow(record)) {
                  const hasChildren = pendingChildren.length > 0
                  const btn = (
                    <Button
                      size="small"
                      danger
                      icon={<RollbackOutlined />}
                      disabled={!canCascadeUnsubscribe}
                      loading={actionLoading === "cascade-unsubscribe"}
                      onClick={confirmCascadeUnsubscribe}
                    >
                      退订{hasChildren ? "全部" : ""}
                    </Button>
                  )
                  return hasChildren ? (
                    <Tooltip title={`退订服务器将一并退订 ${pendingChildren.length} 个关联订单`}>
                      {btn}
                    </Tooltip>
                  ) : (
                    btn
                  )
                }
                return (
                  <Button
                    size="small"
                    danger
                    icon={<RollbackOutlined />}
                    disabled={!record.refund_policy.action_allowed}
                    loading={actionLoading === `unsubscribe-${record.id}`}
                    onClick={() => confirmUnsubscribe(record)}
                  >
                    退订
                  </Button>
                )
              },
            },
          ]}
        />
      </Card>
    </Space>
  )
}
