import {
  ApiOutlined,
  CheckCircleOutlined,
  DatabaseOutlined,
  DeleteOutlined,
  EditOutlined,
  EyeInvisibleOutlined,
  EyeOutlined,
  PlusOutlined,
  ReloadOutlined,
  SearchOutlined,
  SafetyCertificateOutlined,
  ShoppingOutlined,
  StopOutlined,
  TagsOutlined,
  ToolOutlined,
} from "@ant-design/icons"
import {
  Avatar,
  Button,
  Card,
  Empty,
  Input,
  Popconfirm,
  Skeleton,
  Space,
  Table,
  Tag,
  Tooltip,
  Typography,
  theme,
  type TableColumnsType,
} from "antd"
import { useEffect, useMemo, useState, type Key, type ReactNode } from "react"
import type { CloudServer } from "../api/cloud_server"
import type { Product } from "../api/product"
import type { ProductCategory } from "../api/product_catalog"
import type { ProductGroupListItem } from "./ProductGroupSidebar"

const { Text } = Typography

const STATUS_META: Record<Product["status"], { label: string; color: string; icon: ReactNode }> = {
  active: { label: "在售", color: "success", icon: <EyeOutlined /> },
  draft: { label: "草稿", color: "default", icon: <EditOutlined /> },
  hidden: { label: "隐藏", color: "warning", icon: <EyeInvisibleOutlined /> },
  deprecated: { label: "停售", color: "error", icon: <StopOutlined /> },
}

interface Props {
  activeCategory: ProductCategory | null
  activeGroup: ProductGroupListItem | null
  cloudServers: CloudServer[]
  keyword: string
  loading: boolean
  products: Product[]
  batchProcessing?: boolean
  stockSyncing?: boolean
  upstreamStockSnapshots?: Record<number, ProductUpstreamStockSnapshot>
  checking?: boolean
  onBatchDelete: (products: Product[]) => Promise<void>
  onBatchStatusChange: (products: Product[], status: Product["status"]) => Promise<void>
  onBatchVerificationChange?: (products: Product[], requiresRealName: boolean) => Promise<void>
  onGroupVerificationRuleChange?: (requiresRealName: boolean) => Promise<void>
  onSyncStock?: (products: Product[]) => Promise<void>
  onCreate: () => void
  onCheckGroup?: () => void
  onDelete: (product: Product) => void
  onEdit: (product: Product) => void
  onKeywordChange: (keyword: string) => void
}

interface ProductUpstreamStockSnapshot {
  label: string
  color: string
  stockPolicy: "unlimited" | "tracked"
  stock: number
  hidden: boolean
  retired: boolean
  localUpdated: boolean
  error?: string
}

function normalizeText(value: string | number | null | undefined) {
  return String(value ?? "").toLowerCase()
}

function minProductPrice(product: Product) {
  const enabledPrices = product.pricings
    .filter((pricing) => pricing.is_enabled)
    .map((pricing) => pricing.price)
  if (enabledPrices.length > 0) return Math.min(...enabledPrices)
  return product.base_price
}

function formatSpec(product: Product) {
  return [
    product.vcpu ? `${product.vcpu}C` : null,
    product.memory,
    product.disk,
    product.bandwidth,
  ].filter(Boolean).join(" / ") || "-"
}

function canSyncZjmfStock(product: Product) {
  return product.api_type === "zjmf_finance" && Boolean(product.cloud_server_id) && Boolean(String(product.api_identifier ?? "").trim())
}

function localStockLabel(product: Product) {
  return product.stock_policy === "tracked" ? `本地库存 ${product.stock}` : "本地不限库存"
}

function ProductTableSkeleton() {
  return (
    <Space orientation="vertical" size={12} style={{ width: "100%" }}>
      {[0, 1, 2, 3].map((item) => (
        <div
          key={item}
          style={{ border: "1px solid #f0f0f0", borderRadius: 8, padding: "14px 16px" }}
        >
          <Skeleton active title={false} paragraph={{ rows: 2, width: ["45%", "75%"] }} />
        </div>
      ))}
    </Space>
  )
}

export default function ProductTable({
  activeCategory,
  activeGroup,
  cloudServers,
  keyword,
  loading,
  products,
  batchProcessing = false,
  stockSyncing = false,
  upstreamStockSnapshots = {},
  checking = false,
  onBatchDelete,
  onBatchStatusChange,
  onBatchVerificationChange,
  onGroupVerificationRuleChange,
  onSyncStock,
  onCreate,
  onCheckGroup,
  onDelete,
  onEdit,
  onKeywordChange,
}: Props) {
  const { token } = theme.useToken()
  const [selectedRowKeys, setSelectedRowKeys] = useState<Key[]>([])

  const cloudServerMap = useMemo(() => {
    const map = new Map<number, CloudServer>()
    cloudServers.forEach((server) => map.set(server.id, server))
    return map
  }, [cloudServers])

  const visibleProducts = useMemo(() => {
    const q = keyword.trim().toLowerCase()
    if (!q) return products
    return products.filter((product) =>
      [
        product.name,
        product.sku,
        product.cpu_model,
        product.memory,
        product.disk,
        product.bandwidth,
        product.status,
      ].some((value) => normalizeText(value).includes(q))
    )
  }, [keyword, products])

  const selectedProducts = useMemo(
    () => visibleProducts.filter((product) => selectedRowKeys.includes(product.id)),
    [selectedRowKeys, visibleProducts],
  )

  const currentPageSyncableProducts = useMemo(
    () => visibleProducts.filter(canSyncZjmfStock),
    [visibleProducts],
  )

  const selectedSyncableProducts = useMemo(
    () => selectedProducts.filter(canSyncZjmfStock),
    [selectedProducts],
  )

  useEffect(() => {
    const visibleIds = new Set(visibleProducts.map((product) => product.id))
    setSelectedRowKeys((keys) => keys.filter((key) => visibleIds.has(Number(key))))
  }, [visibleProducts])

  const runBatchStatus = async (status: Product["status"]) => {
    await onBatchStatusChange(selectedProducts, status)
    setSelectedRowKeys([])
  }

  const runBatchDelete = async () => {
    await onBatchDelete(selectedProducts)
    setSelectedRowKeys([])
  }

  const runBatchVerification = async (requiresRealName: boolean) => {
    await onBatchVerificationChange?.(selectedProducts, requiresRealName)
    setSelectedRowKeys([])
  }

  const runGroupVerificationRule = async (requiresRealName: boolean) => {
    await onGroupVerificationRuleChange?.(requiresRealName)
    setSelectedRowKeys([])
  }

  const runSyncSelectedStock = async () => {
    await onSyncStock?.(selectedProducts)
  }

  const runSyncCurrentPageStock = async () => {
    await onSyncStock?.(currentPageSyncableProducts)
  }

  const columns = useMemo<TableColumnsType<Product>>(() => [
    {
      title: "产品 / SKU",
      dataIndex: "name",
      width: 300,
      render: (_value, record) => (
        <Space size={12}>
          <Avatar
            shape="square"
            size={38}
            style={{ color: token.colorPrimary, background: token.colorPrimaryBg }}
            icon={<ShoppingOutlined />}
          />
          <Space orientation="vertical" size={0}>
            <Button type="link" style={{ padding: 0 }} onClick={() => onEdit(record)}>
              {record.name}
            </Button>
            <Text type="secondary" style={{ fontSize: 12 }}>{record.sku}</Text>
          </Space>
        </Space>
      ),
    },
    {
      title: "规格",
      key: "spec",
      width: 240,
      render: (_value, record) => (
        <Space orientation="vertical" size={0}>
          <Text>{formatSpec(record)}</Text>
          {record.cpu_model && <Text type="secondary" style={{ fontSize: 12 }}>{record.cpu_model}</Text>}
        </Space>
      ),
    },
    {
      title: "价格",
      key: "price",
      width: 130,
      align: "right",
      render: (_value, record) => (
        <Space orientation="vertical" size={0} align="end">
          <Text strong>¥{minProductPrice(record).toFixed(2)}</Text>
          <Text type="secondary" style={{ fontSize: 12 }}>{record.pricings.length} 个周期</Text>
        </Space>
      ),
    },
    {
      title: "上游",
      key: "upstream",
      width: 220,
      render: (_value, record) => {
        if (record.api_type === "none") {
          return <Tag icon={<ToolOutlined />}>手动开通</Tag>
        }
        const server = record.cloud_server_id ? cloudServerMap.get(record.cloud_server_id) : null
        return (
          <Space orientation="vertical" size={2}>
            <Tag color="blue" icon={<ApiOutlined />}>
              {server?.name ?? `节点 #${record.cloud_server_id ?? "-"}`}
            </Tag>
            {record.api_type === "zjmf_finance" && record.api_identifier && (
              <Tag>PID {record.api_identifier}</Tag>
            )}
          </Space>
        )
      },
    },
    {
      title: "库存",
      key: "stock",
      width: 230,
      render: (_value, record) => {
        const snapshot = upstreamStockSnapshots[record.id]
        const mismatch = Boolean(
          snapshot &&
          (record.stock_policy !== snapshot.stockPolicy || Number(record.stock ?? 0) !== snapshot.stock),
        )
        return (
          <Space orientation="vertical" size={2}>
            <Space wrap size={4}>
              <Tag color={record.stock_policy === "tracked" && record.stock <= 0 ? "red" : "default"}>
                {localStockLabel(record)}
              </Tag>
              {canSyncZjmfStock(record) ? <Tag color="blue">魔方</Tag> : <Tag>本地</Tag>}
            </Space>
            {canSyncZjmfStock(record) ? (
              snapshot ? (
                <>
                  <Space wrap size={4}>
                    <Tag color={snapshot.color}>{snapshot.label}</Tag>
                    <Tag color={mismatch ? "orange" : "green"}>{mismatch ? "不一致" : "一致"}</Tag>
                    {snapshot.localUpdated && <Tag color="blue">已更新</Tag>}
                    {snapshot.hidden && <Tag color="orange">上游隐藏</Tag>}
                    {snapshot.retired && <Tag color="red">上游停售</Tag>}
                  </Space>
                  {snapshot.error && <Text type="danger" style={{ fontSize: 12 }}>{snapshot.error}</Text>}
                </>
              ) : (
                <Tag color="default">上游未同步</Tag>
              )
            ) : (
              <Text type="secondary" style={{ fontSize: 12 }}>非魔方财务产品</Text>
            )}
          </Space>
        )
      },
    },
    {
      title: "状态",
      dataIndex: "status",
      width: 150,
      render: (value: Product["status"], record) => {
        const meta = STATUS_META[value]
        return (
          <Space size={6} wrap>
            <Tag color={meta.color} icon={meta.icon}>{meta.label}</Tag>
            {record.is_featured && <Tag color="gold">推荐</Tag>}
            {record.requires_real_name && <Tag color="purple" icon={<SafetyCertificateOutlined />}>实名</Tag>}
          </Space>
        )
      },
    },
    {
      title: "操作",
      key: "action",
      width: 100,
      align: "right",
      render: (_value, record) => (
        <Space size={4}>
          <Tooltip title="编辑产品">
            <Button type="text" icon={<EditOutlined />} onClick={() => onEdit(record)} />
          </Tooltip>
          <Popconfirm
            title={`删除产品「${record.name}」？`}
            okText="删除"
            cancelText="取消"
            okButtonProps={{ danger: true }}
            onConfirm={() => onDelete(record)}
          >
            <Tooltip title="删除产品">
              <Button type="text" danger icon={<DeleteOutlined />} />
            </Tooltip>
          </Popconfirm>
        </Space>
      ),
    },
  ], [cloudServerMap, onDelete, onEdit, token.colorPrimary, token.colorPrimaryBg, upstreamStockSnapshots])

  return (
    <Card
      variant="outlined"
      title={
        <Space>
          <TagsOutlined />
          {activeGroup?.name ?? activeCategory?.name ?? "产品组"}
          {activeGroup && <Tag>{activeCategory?.name ?? "-"}</Tag>}
          {activeGroup && <Tag icon={<DatabaseOutlined />}>{activeGroup.os_count} 个系统</Tag>}
          {activeGroup?.requires_real_name && <Tag color="purple" icon={<SafetyCertificateOutlined />}>组实名</Tag>}
        </Space>
      }
      extra={
        <Space wrap>
          <Button
            icon={<CheckCircleOutlined />}
            loading={checking}
            disabled={!activeGroup || loading}
            onClick={onCheckGroup}
          >
            检测可用性
          </Button>
          <Button
            icon={<ReloadOutlined />}
            loading={stockSyncing}
            disabled={!activeGroup || loading || !onSyncStock || currentPageSyncableProducts.length === 0}
            onClick={() => void runSyncCurrentPageStock()}
          >
            同步当前页库存
          </Button>
          <Input
            allowClear
            prefix={<SearchOutlined />}
            placeholder="搜索当前组产品 / SKU / 规格"
            value={keyword}
            onChange={(event) => onKeywordChange(event.target.value)}
            style={{ width: 280 }}
            disabled={!activeGroup || loading}
          />
        </Space>
      }
    >
      {!activeGroup ? (
        <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="请选择左侧产品组" />
      ) : loading ? (
        <ProductTableSkeleton />
      ) : visibleProducts.length === 0 ? (
        <Empty
          image={Empty.PRESENTED_IMAGE_SIMPLE}
          description={keyword ? "当前搜索下暂无产品" : "该产品组下暂无产品"}
        >
          <Button type="primary" icon={<PlusOutlined />} onClick={onCreate}>添加产品</Button>
        </Empty>
      ) : (
        <Space orientation="vertical" size={12} style={{ width: "100%" }}>
          <Space wrap>
            <Tag color={selectedProducts.length > 0 ? "blue" : "default"}>
              已选 {selectedProducts.length} 个
            </Tag>
            <Button
              icon={<EyeOutlined />}
              disabled={selectedProducts.length === 0}
              loading={batchProcessing}
              onClick={() => void runBatchStatus("active")}
            >
              批量上架
            </Button>
            <Button
              icon={<EyeInvisibleOutlined />}
              disabled={selectedProducts.length === 0}
              loading={batchProcessing}
              onClick={() => void runBatchStatus("hidden")}
            >
              批量下架
            </Button>
            <Button
              icon={<ReloadOutlined />}
              disabled={!onSyncStock || selectedSyncableProducts.length === 0}
              loading={stockSyncing}
              onClick={() => void runSyncSelectedStock()}
            >
              同步选中库存
            </Button>
            <Button
              icon={<SafetyCertificateOutlined />}
              disabled={!onBatchVerificationChange || selectedProducts.length === 0}
              loading={batchProcessing}
              onClick={() => void runBatchVerification(true)}
            >
              选中需实名
            </Button>
            <Button
              disabled={!onBatchVerificationChange || selectedProducts.length === 0}
              loading={batchProcessing}
              onClick={() => void runBatchVerification(false)}
            >
              取消选中实名
            </Button>
            <Button
              icon={<SafetyCertificateOutlined />}
              disabled={!activeGroup || !onGroupVerificationRuleChange}
              loading={batchProcessing}
              onClick={() => void runGroupVerificationRule(true)}
            >
              整组需实名
            </Button>
            <Button
              disabled={!activeGroup || !onGroupVerificationRuleChange}
              loading={batchProcessing}
              onClick={() => void runGroupVerificationRule(false)}
            >
              取消整组实名
            </Button>
            <Popconfirm
              title={`删除选中的 ${selectedProducts.length} 个产品？`}
              okText="删除"
              cancelText="取消"
              okButtonProps={{ danger: true }}
              disabled={selectedProducts.length === 0}
              onConfirm={() => void runBatchDelete()}
            >
              <Button danger icon={<DeleteOutlined />} disabled={selectedProducts.length === 0} loading={batchProcessing}>
                批量删除
              </Button>
            </Popconfirm>
            {selectedProducts.length > 0 && (
              <Button type="link" onClick={() => setSelectedRowKeys([])} disabled={batchProcessing}>
                取消选择
              </Button>
            )}
          </Space>
          <Table
            rowKey="id"
            size="middle"
            columns={columns}
            dataSource={visibleProducts}
            pagination={false}
            scroll={{ x: 1320 }}
            rowSelection={{
              selectedRowKeys,
              onChange: setSelectedRowKeys,
            }}
          />
        </Space>
      )}
    </Card>
  )
}
