import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"
import {
  ApiOutlined,
  CloudDownloadOutlined,
  DeleteOutlined,
  PlusOutlined,
  SaveOutlined,
  SettingOutlined,
} from "@ant-design/icons"
import {
  Alert,
  Button,
  Card,
  Checkbox,
  Col,
  Divider,
  Empty,
  Form,
  Input,
  InputNumber,
  Modal,
  Popconfirm,
  Row,
  Select,
  Space,
  Switch,
  Table,
  Tabs,
  Tag,
  type TableColumnsType,
} from "antd"
import { toast } from "../../utils/toast"
import { CPU_PRESETS, findCpuPreset } from "./cpuPresets"
import { parseBadges, stringifyBadges } from "./TagInput"
import {
  deleteProduct,
  getZjmfFinanceProductConfig,
  listProvisionInterfaces,
  listProvisionPlugins,
  listCloudResources,
  listZjmfFinanceProducts,
  testProvisionPlugin,
  updateProduct,
  type BillingCycle,
  type CloudResourceItem,
  type ConfigField,
  type ConfigFieldType,
  type ConfigFieldValidationType,
  type Product,
  type ProductApiType,
  type ProductPricingItem,
  type ProvisionConfigField,
  type ProvisionInterface,
  type ProvisionPluginManifest,
  type ProductStatus,
  type ProductType,
  type StockPolicy,
  type ZjmfFinanceProductConfig,
  type ZjmfFinanceProductItem,
} from "../api/product"
import type { CloudServer } from "../api/cloud_server"
import {
  listGroupOsOptions,
  updateGroupOsOptionsPage,
  type OsOptionRow,
  type ProductGroup,
} from "../api/product_catalog"

interface Props {
  initial: Product
  groups: ProductGroup[]
  cloudServers: CloudServer[]
  onSaved: (p: Product) => void
  onDeleted: () => void
  onGroupUpdated?: (g: ProductGroup) => void
}

interface ProductFormValues {
  group_id: number
  sku: string
  name: string
  type: ProductType
  status: ProductStatus
  vcpu: number | null
  cpu_model: string | null
  cpu_base_mhz: number | null
  cpu_turbo_mhz: number | null
  memory: string | null
  disk: string | null
  bandwidth: string | null
  features: string | null
  badges: string[]
  base_price: number
  base_setup_fee: number
  stock_policy: StockPolicy
  stock: number
  min_quantity: number
  max_quantity: number
  sort_order: number
  is_featured: boolean
  requires_real_name: boolean
  trial_enabled: boolean
  trial_days: number
  auto_provision: boolean
  cloud_server_id: number | null
  api_type: ProductApiType
  api_identifier: string | null
  provision_interface_id: number | null
}

const CYCLE_OPTIONS: { value: BillingCycle; label: string }[] = [
  { value: "monthly", label: "月付" },
  { value: "quarterly", label: "季付" },
  { value: "semi_annually", label: "半年付" },
  { value: "annually", label: "年付" },
  { value: "biennially", label: "两年付" },
  { value: "triennially", label: "三年付" },
  { value: "hourly", label: "按时" },
  { value: "daily", label: "按日" },
  { value: "one_time", label: "一次性" },
]

const PRODUCT_TYPE_OPTIONS: { value: ProductType; label: string }[] = [
  { value: "server", label: "云服务器" },
  { value: "hosting", label: "虚拟主机" },
  { value: "domain", label: "域名" },
  { value: "ssl", label: "SSL 证书" },
  { value: "license", label: "软件授权" },
  { value: "other", label: "其他" },
]

const STATUS_OPTIONS: { value: ProductStatus; label: string }[] = [
  { value: "draft", label: "草稿" },
  { value: "active", label: "在售" },
  { value: "hidden", label: "隐藏" },
  { value: "deprecated", label: "停售" },
]

const STOCK_OPTIONS: { value: StockPolicy; label: string }[] = [
  { value: "unlimited", label: "不限库存" },
  { value: "tracked", label: "按库存" },
]

const API_TYPE_OPTIONS: { value: ProductApiType; label: string }[] = [
  { value: "none", label: "不对接" },
  { value: "dcim_cloud_image", label: "魔方云镜像开通" },
  { value: "dcim_cloud_rid", label: "魔方云资源包开通" },
  { value: "zjmf_finance", label: "魔方财务上下游" },
  { value: "plugin", label: "插件开通" },
]

const FIELD_TYPE_OPTIONS: { value: ConfigFieldType; label: string }[] = [
  { value: "fixed", label: "固定值" },
  { value: "user_select", label: "可选项" },
  { value: "input", label: "输入项" },
  { value: "slider", label: "滑动选" },
]

const VALIDATION_OPTIONS: { value: ConfigFieldValidationType; label: string }[] = [
  { value: "none", label: "无限制" },
  { value: "hostname", label: "主机名" },
  { value: "password", label: "密码" },
]

const DCIM_PRESET_FIELDS: ConfigField[] = [
  { def: "ip_num|IP数量", type: "fixed", value: "1" },
  { def: "data_disk_size|数据盘(GB)", type: "fixed", value: "" },
  { def: "hostname|主机名", type: "input", validation: "hostname", hostname_prefix: "", hostname_length: "3-5" },
  { def: "rootpass|密码", type: "input", validation: "password" },
  { def: "client_name|用户名", type: "fixed", value: "" },
]

function parseMemoryToMb(str: string): number | null {
  const m = str.trim().match(/^([\d.]+)\s*(GB|MB|G|M)?$/i)
  if (!m) return null
  const n = Number.parseFloat(m[1])
  const unit = (m[2] ?? "GB").toUpperCase()
  return unit === "MB" || unit === "M" ? Math.round(n) : Math.round(n * 1024)
}

function parseNumberFromStr(str: string): number | null {
  const m = str.trim().match(/^([\d.]+)/)
  if (!m) return null
  const n = Number.parseFloat(m[1])
  return Number.isNaN(n) ? null : n
}

function parseBandwidth(str: string): { inBw: number | null; outBw: number | null } {
  const parts = str.split("/")
  if (parts.length >= 2) {
    return {
      inBw: parseNumberFromStr(parts[0].trim()),
      outBw: parseNumberFromStr(parts[1].trim()),
    }
  }
  const single = parseNumberFromStr(str.trim())
  return { inBw: single, outBw: single }
}

function formatZjmfCyclePrice(cycle: ZjmfFinanceProductConfig["cycles"][number]) {
  return cycle.price === null ? "未返回价格" : `${cycle.price} ${cycle.currency ?? ""}`.trim()
}

function toFiniteNumber(value: string | number | null | undefined) {
  if (value === null || value === undefined || value === "") return null
  const number = typeof value === "number" ? value : Number.parseFloat(String(value))
  return Number.isFinite(number) ? number : null
}

function truthyFlag(value: string | number | null | undefined) {
  if (typeof value === "number") return value !== 0
  return ["1", "true", "yes", "on"].includes(String(value ?? "").trim().toLowerCase())
}

function formatZjmfStock(config: ZjmfFinanceProductConfig | null) {
  if (!config) return null
  const enabled = truthyFlag(config.product.stock_control)
  const qty = toFiniteNumber(config.product.qty)
  if (!enabled) return { label: "库存不限", color: "green" }
  if (qty === null) return { label: "库存已控制，数量未知", color: "orange" }
  return { label: `上游库存 ${qty}`, color: qty > 0 ? "green" : "red" }
}

function splitOptionDef(value: string | null | undefined) {
  const text = String(value ?? "").trim()
  const index = text.indexOf("|")
  if (index < 0) return { value: text, label: text }
  const rawLabel = text.slice(index + 1).trim()
  const labelParts = rawLabel.split("^").filter(Boolean)
  return {
    value: text.slice(0, index).trim(),
    label: rawLabel.includes("^") ? labelParts[labelParts.length - 1] ?? rawLabel : rawLabel,
  }
}

function configOsOptions(fields: ConfigField[] | null | undefined) {
  const osField = (fields ?? []).find((field) => field.def.split("|")[0].trim() === "os")
  if (!osField || osField.type !== "user_select") return []
  return (osField.options ?? [])
    .map((option) => splitOptionDef(option.def))
    .filter((option) => option.value && option.label)
}

function configKey(field: ConfigField) {
  return field.def.split("|")[0].trim()
}

function splitPipeText(value: unknown) {
  const text = String(value ?? "").trim()
  const index = text.indexOf("|")
  if (index < 0) return { raw: text, label: text }
  return {
    raw: text.slice(0, index).trim(),
    label: text.slice(index + 1).trim(),
  }
}

function configLabel(field: ConfigField) {
  const parsed = splitPipeText(field.def)
  return parsed.label || parsed.raw
}

function upstreamValue(value: unknown) {
  if (typeof value === "string") return splitPipeText(value).raw
  return value
}

function isFilled(value: unknown) {
  return value !== null && value !== undefined && value !== ""
}

interface ProductParamPreviewRow {
  key: string
  label: string
  type: string
  value: string
  source: string
}

function productConfigParamPreview(fields: ConfigField[]) {
  return fields
    .map((field): ProductParamPreviewRow | null => {
      const key = configKey(field)
      if (!key) return null
      let value: unknown = null
      let source = "固定值"
      if (field.type === "fixed") {
        value = field.value
      } else if (field.type === "slider") {
        value = field.slider_min ?? field.value
        source = "滑块默认值"
      } else if (field.type === "user_select") {
        value = field.value
        source = "选项值"
      } else if (field.type === "input") {
        value = field.value
        source = "输入值"
      }
      const normalized = upstreamValue(value)
      return {
        key,
        label: configLabel(field),
        type: field.type,
        value: isFilled(normalized) ? String(normalized) : "-",
        source,
      }
    })
    .filter((item): item is ProductParamPreviewRow => Boolean(item))
}

function productConfigParamMap(fields: ConfigField[]) {
  const params: Record<string, unknown> = {}
  for (const row of productConfigParamPreview(fields)) {
    if (row.value !== "-") params[row.key] = row.value
  }
  return params
}

function optionsToText(options: ConfigField["options"]) {
  return (options ?? []).map((item) => item.def).join("\n")
}

function textToOptions(value: string) {
  return value
    .split(/\r?\n/)
    .map((line) => line.trim())
    .filter(Boolean)
    .map((def) => ({ def }))
}

function initialValues(product: Product): ProductFormValues {
  return {
    group_id: product.group_id,
    sku: product.sku,
    name: product.name,
    type: product.type,
    status: product.status,
    vcpu: product.vcpu,
    cpu_model: product.cpu_model,
    cpu_base_mhz: product.cpu_base_mhz,
    cpu_turbo_mhz: product.cpu_turbo_mhz,
    memory: product.memory,
    disk: product.disk,
    bandwidth: product.bandwidth,
    features: product.features,
    badges: parseBadges(product.badges),
    base_price: product.base_price,
    base_setup_fee: product.base_setup_fee,
    stock_policy: product.stock_policy,
    stock: product.stock,
    min_quantity: product.min_quantity,
    max_quantity: product.max_quantity,
    sort_order: product.sort_order,
    is_featured: product.is_featured,
    requires_real_name: product.requires_real_name,
    trial_enabled: product.trial_enabled,
    trial_days: product.trial_days,
    auto_provision: product.auto_provision,
    cloud_server_id: product.cloud_server_id,
    api_type: product.api_type,
    api_identifier: product.api_identifier,
    provision_interface_id: product.provision_interface_id ?? null,
  }
}

function normalizePricings(pricings: Product["pricings"]): ProductPricingItem[] {
  return pricings.map((pricing) => ({
    cycle: pricing.cycle,
    price: pricing.price,
    original_price: pricing.original_price,
    setup_fee: pricing.setup_fee,
    is_enabled: pricing.is_enabled,
    sort_order: pricing.sort_order,
  }))
}

interface ProductPricingEditorProps {
  initialItems: ProductPricingItem[]
  onChange: (items: ProductPricingItem[]) => void
}

const ProductPricingEditor = memo(function ProductPricingEditor({
  initialItems,
  onChange,
}: ProductPricingEditorProps) {
  const [rows, setRows] = useState<ProductPricingItem[]>(initialItems)

  useEffect(() => {
    setRows(initialItems)
  }, [initialItems])

  const commitRows = useCallback(
    (updater: (items: ProductPricingItem[]) => ProductPricingItem[]) => {
      setRows((items) => {
        const next = updater(items)
        onChange(next)
        return next
      })
    },
    [onChange],
  )

  const addPricing = useCallback(() => {
    const taken = new Set(rows.map((pricing) => pricing.cycle))
    const next = CYCLE_OPTIONS.find((cycle) => !taken.has(cycle.value))
    if (!next) {
      toast.error("所有周期都已添加")
      return
    }
    commitRows((items) => [
      ...items,
      { cycle: next.value, price: 0, original_price: null, setup_fee: 0, is_enabled: true, sort_order: items.length },
    ])
  }, [commitRows, rows])

  const updatePricing = useCallback(
    (index: number, patch: Partial<ProductPricingItem>) => {
      commitRows((items) => items.map((item, idx) => idx === index ? { ...item, ...patch } : item))
    },
    [commitRows],
  )

  const removePricing = useCallback(
    (index: number) => {
      commitRows((items) => items.filter((_, idx) => idx !== index))
    },
    [commitRows],
  )

  const columns = useMemo<TableColumnsType<ProductPricingItem>>(
    () => [
      {
        title: "周期",
        dataIndex: "cycle",
        width: 160,
        render: (value, _record, index) => (
          <Select
            value={value}
            options={CYCLE_OPTIONS}
            style={{ width: "100%" }}
            onChange={(cycle) => updatePricing(index, { cycle })}
          />
        ),
      },
      {
        title: "价格",
        dataIndex: "price",
        width: 140,
        render: (value, _record, index) => (
          <InputNumber
            min={0}
            precision={2}
            value={value}
            style={{ width: "100%" }}
            onChange={(price) => updatePricing(index, { price: price ?? 0 })}
          />
        ),
      },
      {
        title: "原价",
        dataIndex: "original_price",
        width: 140,
        render: (value, _record, index) => (
          <InputNumber
            min={0}
            precision={2}
            value={value}
            style={{ width: "100%" }}
            onChange={(original_price) => updatePricing(index, { original_price })}
          />
        ),
      },
      {
        title: "安装费",
        dataIndex: "setup_fee",
        width: 140,
        render: (value, _record, index) => (
          <InputNumber
            min={0}
            precision={2}
            value={value}
            style={{ width: "100%" }}
            onChange={(setup_fee) => updatePricing(index, { setup_fee: setup_fee ?? 0 })}
          />
        ),
      },
      {
        title: "排序",
        dataIndex: "sort_order",
        width: 110,
        render: (value, _record, index) => (
          <InputNumber
            precision={0}
            value={value}
            style={{ width: "100%" }}
            onChange={(sort_order) => updatePricing(index, { sort_order: sort_order ?? 0 })}
          />
        ),
      },
      {
        title: "启用",
        dataIndex: "is_enabled",
        width: 90,
        render: (value, _record, index) => (
          <Switch checked={value} onChange={(is_enabled) => updatePricing(index, { is_enabled })} />
        ),
      },
      {
        title: "操作",
        key: "action",
        width: 80,
        align: "right",
        render: (_value, _record, index) => (
          <Button danger type="text" icon={<DeleteOutlined />} onClick={() => removePricing(index)} />
        ),
      },
    ],
    [removePricing, updatePricing],
  )

  return (
    <Card size="small" title="价格周期" extra={<Button icon={<PlusOutlined />} onClick={addPricing}>添加周期</Button>}>
      <Table
        rowKey={(_record, index) => String(index)}
        columns={columns}
        dataSource={rows}
        pagination={false}
        scroll={{ x: 900 }}
      />
    </Card>
  )
})

interface ProductConfigFieldsEditorProps {
  initialItems: ConfigField[]
  onChange: (items: ConfigField[]) => void
  mode?: "default" | "plugin"
}

const ProductConfigFieldsEditor = memo(function ProductConfigFieldsEditor({
  initialItems,
  onChange,
  mode = "default",
}: ProductConfigFieldsEditorProps) {
  const [rows, setRows] = useState<ConfigField[]>(initialItems)

  useEffect(() => {
    setRows(initialItems)
  }, [initialItems])

  const commitRows = useCallback(
    (updater: (items: ConfigField[]) => ConfigField[]) => {
      setRows((items) => {
        const next = updater(items)
        onChange(next)
        return next
      })
    },
    [onChange],
  )

  const addConfigField = useCallback(() => {
    commitRows((items) => [...items, { def: "", type: "fixed", value: "" }])
  }, [commitRows])

  const updateConfigField = useCallback(
    (index: number, patch: Partial<ConfigField>) => {
      commitRows((items) => items.map((item, idx) => idx === index ? { ...item, ...patch } : item))
    },
    [commitRows],
  )

  const removeConfigField = useCallback(
    (index: number) => {
      commitRows((items) => items.filter((_, idx) => idx !== index))
    },
    [commitRows],
  )

  const columns = useMemo<TableColumnsType<ConfigField>>(
    () => [
      {
        title: "字段定义",
        dataIndex: "def",
        width: 220,
        render: (value, _record, index) => (
          <Input value={value} placeholder="cpu|CPU核心数" onChange={(event) => updateConfigField(index, { def: event.target.value })} />
        ),
      },
      {
        title: "类型",
        dataIndex: "type",
        width: 140,
        render: (value, _record, index) => (
          <Select value={value} options={FIELD_TYPE_OPTIONS} style={{ width: "100%" }} onChange={(type) => updateConfigField(index, { type })} />
        ),
      },
      {
        title: "值 / 选项",
        key: "value",
        width: 520,
        render: (_value, record, index) => {
          if (record.type === "user_select") {
            return (
              <Input.TextArea
                rows={2}
                value={optionsToText(record.options)}
                placeholder="每行一个选项：1|1个IP"
                onChange={(event) => updateConfigField(index, { options: textToOptions(event.target.value) })}
              />
            )
          }
          if (record.type === "input") {
            return (
              <Space.Compact style={{ width: "100%" }}>
                <Select
                  value={record.validation ?? "none"}
                  options={VALIDATION_OPTIONS}
                  style={{ width: 130 }}
                  onChange={(validation) => updateConfigField(index, { validation })}
                />
                <Input
                  value={record.hostname_prefix ?? ""}
                  placeholder="前缀"
                  onChange={(event) => updateConfigField(index, { hostname_prefix: event.target.value })}
                />
                <Input
                  value={record.hostname_length ?? ""}
                  placeholder="位数 3-5"
                  onChange={(event) => updateConfigField(index, { hostname_length: event.target.value })}
                />
              </Space.Compact>
            )
          }
          if (record.type === "slider") {
            return (
              <Space.Compact style={{ width: "100%" }}>
                <InputNumber value={record.slider_min ?? 0} placeholder="最小" onChange={(slider_min) => updateConfigField(index, { slider_min: slider_min ?? 0 })} />
                <InputNumber value={record.slider_max ?? 100} placeholder="最大" onChange={(slider_max) => updateConfigField(index, { slider_max: slider_max ?? 100 })} />
                <InputNumber value={record.slider_step ?? 1} placeholder="步长" onChange={(slider_step) => updateConfigField(index, { slider_step: slider_step ?? 1 })} />
                <InputNumber value={record.slider_unit_price ?? 0} placeholder="单价" onChange={(slider_unit_price) => updateConfigField(index, { slider_unit_price: slider_unit_price ?? 0 })} />
                <Input value={record.slider_unit ?? ""} placeholder="单位" onChange={(event) => updateConfigField(index, { slider_unit: event.target.value })} />
              </Space.Compact>
            )
          }
          return <Input value={record.value ?? ""} onChange={(event) => updateConfigField(index, { value: event.target.value })} />
        },
      },
      {
        title: "操作",
        key: "action",
        width: 80,
        align: "right",
        render: (_value, _record, index) => (
          <Button danger type="text" icon={<DeleteOutlined />} onClick={() => removeConfigField(index)} />
        ),
      },
    ],
    [removeConfigField, updateConfigField],
  )

  return (
    <Card size="small" title="开通参数" extra={<Button icon={<PlusOutlined />} onClick={addConfigField}>添加字段</Button>}>
      {mode === "plugin" ? (
        <Alert
          type="info"
          showIcon
          style={{ marginBottom: 12 }}
          title="这些字段会在插件开通时解析为 context.upstream_params"
          description="字段定义按 name|显示名 填写；固定值和选项值按 value|显示值 填写，真正传给上游的是 | 前面的 name/value。"
        />
      ) : null}
      <Table rowKey={(_record, index) => String(index)} columns={columns} dataSource={rows} pagination={false} scroll={{ x: 1100 }} />
    </Card>
  )
})

const OS_FAMILY_ORDER = [
  "windows",
  "ubuntu",
  "debian",
  "centos",
  "rocky",
  "almalinux",
  "fedora",
  "alpine",
  "arch",
  "freebsd",
  "other",
] as const

const OS_FAMILY_META: Record<string, { label: string; color: string }> = {
  windows: { label: "Windows", color: "blue" },
  ubuntu: { label: "Ubuntu", color: "orange" },
  debian: { label: "Debian", color: "red" },
  centos: { label: "CentOS", color: "purple" },
  rocky: { label: "Rocky Linux", color: "green" },
  almalinux: { label: "AlmaLinux", color: "cyan" },
  fedora: { label: "Fedora", color: "geekblue" },
  alpine: { label: "Alpine", color: "lime" },
  arch: { label: "Arch Linux", color: "processing" },
  freebsd: { label: "FreeBSD", color: "volcano" },
  other: { label: "其他系统", color: "default" },
}

function resolveOsFamily(item: CloudResourceItem) {
  const text = `${item.label} ${item.extra ?? ""}`.toLowerCase()
  if (text.includes("windows") || text.includes("win")) return "windows"
  if (text.includes("ubuntu")) return "ubuntu"
  if (text.includes("debian")) return "debian"
  if (text.includes("centos")) return "centos"
  if (text.includes("rocky")) return "rocky"
  if (text.includes("almalinux") || text.includes("alma linux")) return "almalinux"
  if (text.includes("fedora")) return "fedora"
  if (text.includes("alpine")) return "alpine"
  if (text.includes("arch")) return "arch"
  if (text.includes("freebsd")) return "freebsd"
  return "other"
}

function groupOsImages(items: CloudResourceItem[]) {
  const grouped = new Map<string, CloudResourceItem[]>()
  for (const item of items) {
    const family = resolveOsFamily(item)
    grouped.set(family, [...(grouped.get(family) ?? []), item])
  }
  return OS_FAMILY_ORDER
    .filter((family) => grouped.has(family))
    .map((family) => ({
      family,
      meta: OS_FAMILY_META[family],
      items: grouped.get(family) ?? [],
    }))
}

interface ProductOsOptionsEditorProps {
  currentGroup: ProductGroup | null
  cloudServerId: number | null | undefined
  productConfig?: ConfigField[] | null
}

const ProductOsOptionsEditor = memo(function ProductOsOptionsEditor({
  currentGroup,
  cloudServerId,
  productConfig,
}: ProductOsOptionsEditorProps) {
  const [osOptions, setOsOptions] = useState<OsOptionRow[]>([])
  const [osImages, setOsImages] = useState<CloudResourceItem[]>([])
  const [imageModalOpen, setImageModalOpen] = useState(false)
  const [selectedImageIds, setSelectedImageIds] = useState<Set<string>>(new Set())
  const [osLoading, setOsLoading] = useState(false)
  const [osFetching, setOsFetching] = useState(false)
  const [osSaving, setOsSaving] = useState(false)
  const [osPage, setOsPage] = useState(1)
  const [osPageSize, setOsPageSize] = useState(20)
  const [osTotal, setOsTotal] = useState(0)

  useEffect(() => {
    setOsPage(1)
    setOsOptions([])
    setOsTotal(0)
  }, [currentGroup?.id])

  useEffect(() => {
    if (!currentGroup) return
    let ignore = false
    const offset = (osPage - 1) * osPageSize
    setOsLoading(true)
    listGroupOsOptions(currentGroup.id, offset, osPageSize)
      .then((res) => {
        if (ignore) return
        const page = res.data
        setOsOptions(page?.items ?? [])
        setOsTotal(page?.total ?? 0)
      })
      .catch((e: unknown) => {
        if (ignore) return
        const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
        toast.error(detail || "系统列表加载失败")
      })
      .finally(() => {
        if (!ignore) setOsLoading(false)
      })
    return () => {
      ignore = true
    }
  }, [currentGroup, osPage, osPageSize])

  const fetchOsImages = async () => {
    if (!cloudServerId) {
      toast.error("请先在自动开通中绑定云接口")
      return
    }
    setOsFetching(true)
    try {
      const res = await listCloudResources("image", cloudServerId)
      const nextImages = res.data ?? []
      setOsImages(nextImages)
      setSelectedImageIds(new Set())
      setImageModalOpen(true)
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "拉取镜像失败")
    } finally {
      setOsFetching(false)
    }
  }

  const saveOsOptions = async () => {
    if (!currentGroup) return
    setOsSaving(true)
    try {
      const offset = (osPage - 1) * osPageSize
      const res = await updateGroupOsOptionsPage(currentGroup.id, {
        offset,
        limit: osPageSize,
        items: osOptions.map((item) => ({ label: item.label, value: item.value })),
      })
      toast.success("系统列表已保存")
      if (res.data) {
        setOsOptions(res.data.items)
        setOsTotal(res.data.total)
      }
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "保存失败")
    } finally {
      setOsSaving(false)
    }
  }

  const selectedOsColumns = useMemo<TableColumnsType<OsOptionRow>>(
    () => [
      {
        title: "系统名称",
        dataIndex: "label",
        render: (value, _record, index) => (
          <Input value={value} onChange={(event) => setOsOptions((items) => items.map((item, idx) => idx === index ? { ...item, label: event.target.value } : item))} />
        ),
      },
      {
        title: "OS ID",
        dataIndex: "value",
        width: 160,
        render: (value, _record, index) => (
          <InputNumber min={0} precision={0} value={value} style={{ width: "100%" }} onChange={(next) => setOsOptions((items) => items.map((item, idx) => idx === index ? { ...item, value: next ?? 0 } : item))} />
        ),
      },
      {
        title: "操作",
        key: "action",
        width: 80,
        align: "right",
        render: (_value, _record, index) => (
          <Button danger type="text" icon={<DeleteOutlined />} onClick={() => setOsOptions((items) => items.filter((_, idx) => idx !== index))} />
        ),
      },
    ],
    [],
  )

  const groupedImages = useMemo(() => groupOsImages(osImages), [osImages])
  const selectedImageRows = useMemo(
    () => osImages.filter((item) => selectedImageIds.has(item.id)),
    [osImages, selectedImageIds],
  )
  const upstreamOsOptions = useMemo(() => configOsOptions(productConfig), [productConfig])

  const toggleImage = useCallback((id: string, checked: boolean) => {
    setSelectedImageIds((prev) => {
      const next = new Set(prev)
      if (checked) next.add(id)
      else next.delete(id)
      return next
    })
  }, [])

  const selectAllImages = useCallback(() => {
    const existing = new Set(osOptions.map((item) => item.value))
    setSelectedImageIds(new Set(osImages.filter((item) => !existing.has(Number(item.id))).map((item) => item.id)))
  }, [osImages, osOptions])

  const clearImageSelection = useCallback(() => {
    setSelectedImageIds(new Set())
  }, [])

  const selectFamilyImages = useCallback((items: CloudResourceItem[]) => {
    const existing = new Set(osOptions.map((item) => item.value))
    setSelectedImageIds((prev) => {
      const next = new Set(prev)
      for (const item of items) {
        if (!existing.has(Number(item.id))) next.add(item.id)
      }
      return next
    })
  }, [osOptions])

  const addSelectedImages = useCallback(() => {
    if (selectedImageRows.length === 0) {
      toast.error("请先选择要添加的系统")
      return
    }
    setOsOptions((items) => {
      const existing = new Set(items.map((item) => item.value))
      const additions = selectedImageRows
        .map((item, idx) => ({ label: item.label, value: Number(item.id), index: -Date.now() - idx }))
        .filter((item) => Number.isFinite(item.value))
        .filter((item) => !existing.has(item.value))
      if (additions.length === 0) {
        toast.error("所选系统已在当前页")
        return items
      }
      toast.success(`已添加 ${additions.length} 个系统，记得保存当前页`)
      return [...items, ...additions]
    })
    setImageModalOpen(false)
  }, [selectedImageRows])

  return (
    <Space orientation="vertical" size={16} style={{ width: "100%" }}>
      <Alert
        type="warning"
        showIcon
        title="系统列表属于产品组"
        description="这里保存的是当前产品所属产品组的系统列表，同组产品会共享这些系统。魔方财务商品如果自带操作系统，前台会优先使用当前产品配置里的上游系统。"
      />
      {upstreamOsOptions.length > 0 && (
        <Card size="small" title={`当前产品上游系统（${upstreamOsOptions.length} 个）`}>
          <Space wrap>
            {upstreamOsOptions.map((option) => (
              <Tag key={`${option.value}-${option.label}`}>
                {option.label} · {option.value}
              </Tag>
            ))}
          </Space>
        </Card>
      )}
      <Space>
        <Tag color="blue">{currentGroup?.name ?? "未选择产品组"}</Tag>
        <Button icon={<CloudDownloadOutlined />} loading={osFetching} onClick={fetchOsImages}>拉取上游镜像</Button>
        {osImages.length > 0 && <Button onClick={() => setImageModalOpen(true)}>打开镜像选择器</Button>}
        <Button type="primary" icon={<SaveOutlined />} loading={osSaving} onClick={saveOsOptions}>保存当前页</Button>
      </Space>
      <Row gutter={16}>
        <Col span={16}>
          <Card size="small" title={`已选系统（共 ${osTotal} 个）`} extra={<Button icon={<PlusOutlined />} onClick={() => setOsOptions((items) => [...items, { label: "", value: 0, index: -Date.now() }])}>添加</Button>}>
            <Table
              rowKey={(record, index) => `${record.index}-${index}`}
              loading={osLoading}
              columns={selectedOsColumns}
              dataSource={osOptions}
              pagination={{
                current: osPage,
                pageSize: osPageSize,
                total: osTotal,
                showSizeChanger: true,
                showTotal: (total) => `共 ${total} 个系统`,
                onChange: (page, pageSize) => {
                  setOsPage(page)
                  setOsPageSize(pageSize)
                },
              }}
              locale={{ emptyText: <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无系统" /> }}
            />
          </Card>
        </Col>
        <Col span={8}>
          <Card size="small" title="上游镜像">
            {osImages.length > 0 ? (
              <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                <Alert type="success" showIcon title={`已拉取 ${osImages.length} 个镜像`} />
                <Button block onClick={() => setImageModalOpen(true)}>按系统类型选择</Button>
              </Space>
            ) : (
              <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="请先拉取镜像" />
            )}
          </Card>
        </Col>
      </Row>
      <Modal
        open={imageModalOpen}
        title="选择上游系统镜像"
        width={920}
        destroyOnHidden
        onCancel={() => setImageModalOpen(false)}
        footer={[
          <Button key="clear" onClick={clearImageSelection}>清空选择</Button>,
          <Button key="all" onClick={selectAllImages}>全选全部系统</Button>,
          <Button key="cancel" onClick={() => setImageModalOpen(false)}>取消</Button>,
          <Button key="add" type="primary" onClick={addSelectedImages}>
            添加所选（{selectedImageIds.size}）
          </Button>,
        ]}
      >
        <Space orientation="vertical" size={16} style={{ width: "100%" }}>
          <Alert
            type="info"
            showIcon
            title="镜像已按系统类型分类"
            description="这里展示本次拉取到的全部镜像，不分页。勾选后添加到当前系统页，保存当前页后生效。"
          />
          <div style={{ maxHeight: 560, overflowY: "auto", paddingRight: 4 }}>
            <Space orientation="vertical" size={16} style={{ width: "100%" }}>
              {groupedImages.length === 0 ? (
                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无镜像" />
              ) : groupedImages.map((group) => (
                <Card
                  key={group.family}
                  size="small"
                  title={<Space><Tag color={group.meta.color}>{group.meta.label}</Tag><span>{group.items.length} 个</span></Space>}
                  extra={<Button size="small" onClick={() => selectFamilyImages(group.items)}>全选本类</Button>}
                >
                  <Row gutter={[8, 8]}>
                    {group.items.map((item) => {
                      const checked = selectedImageIds.has(item.id)
                      const exists = osOptions.some((os) => os.value === Number(item.id))
                      return (
                        <Col span={12} key={item.id}>
                          <Checkbox
                            checked={checked}
                            disabled={exists}
                            onChange={(event) => toggleImage(item.id, event.target.checked)}
                          >
                            <Space orientation="vertical" size={0}>
                              <span>{item.label}</span>
                              <span style={{ color: "#8c8c8c", fontSize: 12 }}>
                                ID {item.id}{item.extra ? ` · ${item.extra}` : ""}
                                {exists ? " · 当前页已添加" : ""}
                              </span>
                            </Space>
                          </Checkbox>
                        </Col>
                      )
                    })}
                  </Row>
                </Card>
              ))}
            </Space>
          </div>
        </Space>
      </Modal>
    </Space>
  )
})

export default function ProductFormBody({
  initial,
  groups,
  cloudServers,
  onSaved,
  onDeleted,
}: Props) {
  const [form] = Form.useForm<ProductFormValues>()
  const [saving, setSaving] = useState(false)
  const [pricingSeed, setPricingSeed] = useState<ProductPricingItem[]>(() => normalizePricings(initial.pricings))
  const pricingsRef = useRef<ProductPricingItem[]>(pricingSeed)
  const [configSeed, setConfigSeed] = useState<ConfigField[]>(() => initial.provision_config ?? [])
  const configFieldsRef = useRef<ConfigField[]>(configSeed)
  const [zjmfProducts, setZjmfProducts] = useState<ZjmfFinanceProductItem[]>([])
  const [zjmfProductLoading, setZjmfProductLoading] = useState(false)
  const [zjmfProductMeta, setZjmfProductMeta] = useState<{ count: number; currency: string | null } | null>(null)
  const [zjmfConfig, setZjmfConfig] = useState<ZjmfFinanceProductConfig | null>(null)
  const [zjmfConfigLoading, setZjmfConfigLoading] = useState(false)
  const [provisionPlugins, setProvisionPlugins] = useState<ProvisionPluginManifest[]>([])
  const [provisionInterfaces, setProvisionInterfaces] = useState<ProvisionInterface[]>([])
  const [pluginLoading, setPluginLoading] = useState(false)
  const [interfaceLoading, setInterfaceLoading] = useState(false)
  const [pluginTesting, setPluginTesting] = useState(false)

  const groupId = Form.useWatch("group_id", form)
  const apiType = Form.useWatch("api_type", form)
  const cloudServerId = Form.useWatch("cloud_server_id", form)
  const apiIdentifier = Form.useWatch("api_identifier", form)
  const provisionInterfaceId = Form.useWatch("provision_interface_id", form)
  const autoProvision = Form.useWatch("auto_provision", form)
  const cpuModel = Form.useWatch("cpu_model", form)
  const currentGroup = useMemo(() => groups.find((group) => group.id === groupId) ?? null, [groupId, groups])
  const matchedPreset = useMemo(() => findCpuPreset(cpuModel ?? ""), [cpuModel])
  const zjmfStock = useMemo(() => formatZjmfStock(zjmfConfig), [zjmfConfig])

  useEffect(() => {
    if (apiType !== "plugin" || !provisionInterfaceId || !apiIdentifier) return
    const current = provisionInterfaces.find((item) => item.id === Number(provisionInterfaceId))
    if (current && current.plugin_id !== String(apiIdentifier).trim()) {
      form.setFieldsValue({ provision_interface_id: null })
    }
  }, [apiIdentifier, apiType, form, provisionInterfaceId, provisionInterfaces])

  useEffect(() => {
    form.setFieldsValue(initialValues(initial))
    const nextPricings = normalizePricings(initial.pricings)
    pricingsRef.current = nextPricings
    setPricingSeed(nextPricings)
    const nextConfigFields = initial.provision_config ?? []
    configFieldsRef.current = nextConfigFields
    setConfigSeed(nextConfigFields)
  }, [form, initial])

  useEffect(() => {
    setPluginLoading(true)
    listProvisionPlugins()
      .then((res) => setProvisionPlugins(res.data ?? []))
      .catch((e: unknown) => {
        const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
        toast.error(detail || "加载开通插件失败")
      })
      .finally(() => setPluginLoading(false))
  }, [])

  const loadProvisionInterfaces = useCallback(async () => {
    setInterfaceLoading(true)
    try {
      const res = await listProvisionInterfaces()
      setProvisionInterfaces(res.data ?? [])
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "加载开通接口失败")
    } finally {
      setInterfaceLoading(false)
    }
  }, [])

  useEffect(() => {
    void loadProvisionInterfaces()
  }, [loadProvisionInterfaces])

  const handlePricingsChange = useCallback((items: ProductPricingItem[]) => {
    pricingsRef.current = items
  }, [])

  const handleConfigFieldsChange = useCallback((items: ConfigField[]) => {
    configFieldsRef.current = items
  }, [])

  const loadZjmfProducts = useCallback(async (silent = false) => {
    if (apiType !== "zjmf_finance" || !cloudServerId) return
    setZjmfProductLoading(true)
    try {
      const res = await listZjmfFinanceProducts(cloudServerId)
      const data = res.data
      setZjmfProducts(data?.products ?? [])
      setZjmfProductMeta(data ? { count: data.count, currency: data.currency } : null)
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      if (!silent) toast.error(detail || "拉取魔方财务商品失败")
      setZjmfProducts([])
      setZjmfProductMeta(null)
    } finally {
      setZjmfProductLoading(false)
    }
  }, [apiType, cloudServerId])

  useEffect(() => {
    setZjmfConfig(null)
    if (apiType !== "zjmf_finance" || !cloudServerId) {
      setZjmfProducts([])
      setZjmfProductMeta(null)
      return
    }
    void loadZjmfProducts(true)
  }, [apiType, cloudServerId, loadZjmfProducts])

  const loadZjmfConfig = useCallback(async () => {
    const pid = String(apiIdentifier ?? "").trim()
    if (apiType !== "zjmf_finance" || !cloudServerId || !pid) {
      toast.error("请先选择魔方财务节点和上游产品")
      return
    }
    setZjmfConfigLoading(true)
    try {
      const res = await getZjmfFinanceProductConfig(cloudServerId, pid)
      setZjmfConfig(res.data ?? null)
      toast.success("已拉取上游配置")
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "拉取魔方财务配置失败")
      setZjmfConfig(null)
    } finally {
      setZjmfConfigLoading(false)
    }
  }, [apiIdentifier, apiType, cloudServerId])

  const groupOptions = useMemo(
    () => groups.map((group) => ({ value: group.id, label: group.name })),
    [groups],
  )

  const cpuOptions = useMemo(
    () => CPU_PRESETS.map((preset) => ({
      value: preset.model,
      label: `${preset.model} · ${preset.family} · ${(preset.baseMhz / 1000).toFixed(1)}-${(preset.turboMhz / 1000).toFixed(1)} GHz`,
      preset,
    })),
    [],
  )

  const cloudServerOptions = useMemo(
    () =>
      cloudServers
        .filter((server) => {
          if (apiType === "dcim_cloud_image") {
            return server.server_type === "dcimcloud" && server.account_type === "admin"
          }
          if (apiType === "dcim_cloud_rid") {
            return server.server_type === "dcimcloud" && server.account_type === "agent"
          }
          if (apiType === "zjmf_finance") {
            return server.server_type === "zjmf_finance"
          }
          return false
        })
        .map((server) => {
          const typeLabel = server.server_type === "zjmf_finance" ? "魔方财务" : server.account_type === "admin" ? "自营" : "资源池"
          return { value: server.id, label: `${server.name} · ${typeLabel}` }
        }),
    [apiType, cloudServers],
  )

  const zjmfProductOptions = useMemo(
    () =>
      zjmfProducts.map((product) => ({
        value: product.id,
        label: `${product.name} · PID ${product.id}${product.group_name ? ` · ${product.group_name}` : ""}`,
      })),
    [zjmfProducts],
  )

  const provisionPluginOptions = useMemo(
    () =>
      provisionPlugins.map((plugin) => ({
        value: plugin.id,
        label: `${plugin.name} / ${plugin.id} / ${plugin.version}`,
      })),
    [provisionPlugins],
  )

  const provisionInterfaceOptions = useMemo(
    () =>
      provisionInterfaces
        .filter((item) => !apiIdentifier || item.plugin_id === String(apiIdentifier).trim())
        .map((item) => ({
          value: item.id,
          label: `${item.name} / ${item.plugin_name ?? item.plugin_id}${item.enabled ? "" : " / 已禁用"}`,
          disabled: !item.enabled,
        })),
    [apiIdentifier, provisionInterfaces],
  )

  const selectedZjmfProduct = useMemo(
    () => zjmfProducts.find((product) => product.id === String(apiIdentifier ?? "").trim()) ?? null,
    [apiIdentifier, zjmfProducts],
  )

  const selectedProvisionPlugin = useMemo(
    () => provisionPlugins.find((plugin) => plugin.id === String(apiIdentifier ?? "").trim()) ?? null,
    [apiIdentifier, provisionPlugins],
  )

  const selectedProvisionInterface = useMemo(
    () => provisionInterfaces.find((item) => item.id === Number(provisionInterfaceId)) ?? null,
    [provisionInterfaceId, provisionInterfaces],
  )

  const pluginParamPreview = useMemo(
    () => productConfigParamPreview(configSeed),
    [configSeed],
  )

  const pluginParamPreviewColumns = useMemo<TableColumnsType<ProductParamPreviewRow>>(
    () => [
      { title: "参数名", dataIndex: "key", width: 150, render: (value) => <Tag>{value}</Tag> },
      { title: "显示名", dataIndex: "label", width: 160 },
      { title: "类型", dataIndex: "type", width: 110, render: (value) => <Tag>{value}</Tag> },
      { title: "传递值", dataIndex: "value", width: 160 },
      { title: "来源", dataIndex: "source" },
    ],
    [],
  )

  const pluginRecommendedColumns = useMemo<TableColumnsType<ProvisionConfigField>>(
    () => [
      { title: "参数名", dataIndex: "key", width: 140, render: (value) => <Tag>{value}</Tag> },
      { title: "显示名", dataIndex: "label", width: 150 },
      {
        title: "默认值",
        dataIndex: "default",
        width: 150,
        render: (value) => (value === undefined || value === null || value === "" ? "-" : String(value)),
      },
      { title: "必填", dataIndex: "required", width: 90, render: (value) => (value ? <Tag color="red">必填</Tag> : <Tag>可选</Tag>) },
      { title: "说明", dataIndex: "help" },
    ],
    [],
  )

  const applySpecFields = () => {
    const values = form.getFieldsValue()
    const configFields = configFieldsRef.current
    const existingKeys = new Set(configFields.map(configKey).filter(Boolean))
    const next: ConfigField[] = []
    const tryAdd = (key: string, label: string, value: string) => {
      if (!existingKeys.has(key)) next.push({ def: `${key}|${label}`, type: "fixed", value })
    }
    if (values.vcpu != null) tryAdd("cpu", "CPU核心数", String(values.vcpu))
    if (values.memory?.trim()) {
      const mb = parseMemoryToMb(values.memory)
      tryAdd("memory", "内存(MB)", mb !== null ? String(mb) : "")
    }
    if (values.disk?.trim()) {
      const gb = parseNumberFromStr(values.disk)
      tryAdd("system_disk_size", "系统盘(GB)", gb !== null ? String(gb) : "")
    }
    if (values.bandwidth?.trim()) {
      const { inBw, outBw } = parseBandwidth(values.bandwidth)
      tryAdd("in_bw", "进带宽(Mbps)", inBw !== null ? String(inBw) : "")
      tryAdd("out_bw", "出带宽(Mbps)", outBw !== null ? String(outBw) : "")
    }
    if (next.length === 0) {
      toast.error("详情规格均已存在于配置列表，已跳过")
      return
    }
    const merged = [...configFields, ...next]
    configFieldsRef.current = merged
    setConfigSeed(merged)
  }

  const applyDcimPreset = () => {
    const values = form.getFieldsValue()
    const configFields = configFieldsRef.current
    const existingKeys = new Set(configFields.map(configKey).filter(Boolean))
    const next: ConfigField[] = []
    const tryAdd = (field: ConfigField) => {
      if (!existingKeys.has(configKey(field))) next.push(field)
    }
    if (values.vcpu != null) tryAdd({ def: "cpu|CPU核心数", type: "fixed", value: String(values.vcpu) })
    if (values.memory?.trim()) {
      const mb = parseMemoryToMb(values.memory)
      tryAdd({ def: "memory|内存(MB)", type: "fixed", value: mb !== null ? String(mb) : "" })
    }
    if (values.disk?.trim()) {
      const gb = parseNumberFromStr(values.disk)
      tryAdd({ def: "system_disk_size|系统盘(GB)", type: "fixed", value: gb !== null ? String(gb) : "" })
    }
    if (values.bandwidth?.trim()) {
      const { inBw, outBw } = parseBandwidth(values.bandwidth)
      tryAdd({ def: "in_bw|进带宽(Mbps)", type: "fixed", value: inBw !== null ? String(inBw) : "" })
      tryAdd({ def: "out_bw|出带宽(Mbps)", type: "fixed", value: outBw !== null ? String(outBw) : "" })
    }
    DCIM_PRESET_FIELDS.forEach(tryAdd)
    if (next.length === 0) {
      toast.error("预设字段均已存在，已跳过")
      return
    }
    const merged = [...configFields, ...next]
    configFieldsRef.current = merged
    setConfigSeed(merged)
  }

  const fieldOptionDef = (option: { label: string; value: string | number | boolean }) => {
    const raw = String(option.value)
    return raw.includes("|") ? raw : `${raw}|${option.label}`
  }

  const applyPluginParamPreset = () => {
    if (!selectedProvisionPlugin) {
      toast.error("请先选择开通插件")
      return
    }
    const fields = selectedProvisionPlugin.upstream_param_fields ?? []
    if (fields.length === 0) {
      toast.error("该插件未声明推荐上游参数")
      return
    }
    const configFields = configFieldsRef.current
    const existingKeys = new Set(configFields.map(configKey).filter(Boolean))
    const next: ConfigField[] = []
    for (const field of fields) {
      if (!field.key || existingKeys.has(field.key)) continue
      if (field.type === "select" && field.options?.length) {
        const options = field.options.map(fieldOptionDef).map((def) => ({ def }))
        const value = field.default !== undefined && field.default !== null ? String(field.default) : options[0]?.def ?? ""
        next.push({ def: `${field.key}|${field.label}`, type: "user_select", value, options })
      } else {
        const value = field.default !== undefined && field.default !== null ? String(field.default) : ""
        next.push({ def: `${field.key}|${field.label}`, type: "fixed", value })
      }
    }
    if (next.length === 0) {
      toast.error("推荐参数均已存在，已跳过")
      return
    }
    const merged = [...configFields, ...next]
    configFieldsRef.current = merged
    setConfigSeed(merged)
    toast.success(`已添加 ${next.length} 个插件推荐参数`)
  }

  const runPluginTest = async () => {
    const pluginId = String(form.getFieldValue("api_identifier") ?? "").trim()
    if (apiType !== "plugin" || !pluginId) {
      toast.error("请先选择开通插件")
      return
    }
    const interfaceId = Number(form.getFieldValue("provision_interface_id") || 0)
    if (!interfaceId) {
      toast.error("请先选择开通接口")
      return
    }
    setPluginTesting(true)
    try {
      const productConfig = configFieldsRef.current
      const res = await testProvisionPlugin(pluginId, {
        provision_interface_id: interfaceId,
        product_id: initial.id,
        product_sku: initial.sku,
        product_name: String(form.getFieldValue("name") ?? initial.name ?? ""),
        upstream_params: productConfigParamMap(productConfig),
        product_config: productConfig,
      })
      const data = res.data
      const ok = data?.ok !== false
      const message = typeof data?.message === "string" ? data.message : ok ? "插件测试通过" : "插件测试失败"
      if (ok) {
        toast.success(message)
      } else {
        toast.error(message)
      }
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "插件测试失败")
    } finally {
      setPluginTesting(false)
    }
  }

  const saveProduct = async () => {
    await form.validateFields()
    const values = form.getFieldsValue(true) as ProductFormValues
    if (values.auto_provision && values.api_type !== "none" && values.api_type !== "plugin" && !values.cloud_server_id) {
      toast.error("启用上游对接时必须选择云接口")
      return
    }
    if (values.auto_provision && values.api_type === "zjmf_finance" && !values.api_identifier?.trim()) {
      toast.error("魔方财务产品必须填写上游产品 ID")
      return
    }
    if (values.auto_provision && values.api_type === "plugin" && !values.api_identifier?.trim()) {
      toast.error("插件开通产品必须选择开通插件")
      return
    }
    if (values.auto_provision && values.api_type === "plugin" && !values.provision_interface_id) {
      toast.error("插件开通产品必须选择开通接口")
      return
    }
    setSaving(true)
    try {
      const payload = {
        group_id: values.group_id,
        sku: values.sku.trim(),
        name: values.name.trim(),
        type: values.type,
        status: values.status,
        vcpu: values.vcpu ?? null,
        cpu_model: values.cpu_model?.trim() || null,
        cpu_base_mhz: values.cpu_base_mhz ?? null,
        cpu_turbo_mhz: values.cpu_turbo_mhz ?? null,
        memory: values.memory?.trim() || null,
        disk: values.disk?.trim() || null,
        bandwidth: values.bandwidth?.trim() || null,
        features: values.features?.trim() || null,
        badges: stringifyBadges(values.badges ?? []),
        base_price: values.base_price,
        base_setup_fee: values.base_setup_fee,
        stock_policy: values.stock_policy,
        stock: values.stock,
        min_quantity: values.min_quantity,
        max_quantity: values.max_quantity,
        sort_order: values.sort_order,
        is_featured: !!values.is_featured,
        requires_real_name: !!values.requires_real_name,
        trial_enabled: !!values.trial_enabled,
        trial_days: values.trial_days,
        auto_provision: !!values.auto_provision,
        cloud_server_id: values.auto_provision && values.api_type !== "none" && values.api_type !== "plugin" ? values.cloud_server_id : null,
        api_type: values.auto_provision ? values.api_type : "none",
        api_identifier: values.auto_provision && values.api_type !== "none" ? values.api_identifier?.trim() || null : null,
        provision_interface_id: values.auto_provision && values.api_type === "plugin" ? values.provision_interface_id : null,
        provision_config: configFieldsRef.current.length > 0 ? configFieldsRef.current : null,
        pricings: pricingsRef.current,
      }
      const res = await updateProduct(initial.id, payload)
      toast.success("已保存")
      if (res.data) onSaved(res.data)
    } catch (e: unknown) {
      if ((e as { errorFields?: unknown[] })?.errorFields) return
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "保存失败")
    } finally {
      setSaving(false)
    }
  }

  const removeProduct = async () => {
    try {
      await deleteProduct(initial.id)
      toast.success("已删除")
      onDeleted()
    } catch (e: unknown) {
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "删除失败")
    }
  }

  return (
    <Card
      variant="outlined"
      actions={[
        <Popconfirm key="delete" title={`删除产品「${initial.name}」？`} okText="删除" cancelText="取消" okButtonProps={{ danger: true }} onConfirm={removeProduct}>
          <Button danger type="text" icon={<DeleteOutlined />}>删除产品</Button>
        </Popconfirm>,
        <Button key="save" type="primary" icon={<SaveOutlined />} loading={saving} onClick={saveProduct}>保存修改</Button>,
      ]}
    >
      <Form form={form} layout="vertical" initialValues={initialValues(initial)}>
        <Tabs
          items={[
            {
              key: "detail",
              label: "详情",
              children: (
                <Space orientation="vertical" size={18} style={{ width: "100%" }}>
                  <Row gutter={16}>
                    <Col span={12}>
                      <Form.Item label="所属产品组" name="group_id" rules={[{ required: true, message: "请选择产品组" }]}>
                        <Select showSearch optionFilterProp="label" options={groupOptions} />
                      </Form.Item>
                    </Col>
                    <Col span={12}>
                      <Form.Item label="SKU" name="sku" rules={[{ required: true, message: "请填写 SKU" }]}>
                        <Input />
                      </Form.Item>
                    </Col>
                  </Row>
                  <Form.Item label="名称" name="name" rules={[{ required: true, message: "请填写名称" }]}>
                    <Input />
                  </Form.Item>
                  <Row gutter={16}>
                    <Col span={12}>
                      <Form.Item label="形态" name="type">
                        <Select options={PRODUCT_TYPE_OPTIONS} />
                      </Form.Item>
                    </Col>
                    <Col span={12}>
                      <Form.Item label="上架状态" name="status">
                        <Select options={STATUS_OPTIONS} />
                      </Form.Item>
                    </Col>
                  </Row>
                  <Divider>规格</Divider>
                  <Row gutter={16}>
                    <Col span={6}>
                      <Form.Item label="vCPU" name="vcpu"><InputNumber min={0} style={{ width: "100%" }} /></Form.Item>
                    </Col>
                    <Col span={10}>
                      <Form.Item label="CPU 型号" name="cpu_model">
                        <Select
                          allowClear
                          showSearch
                          optionFilterProp="label"
                          options={cpuOptions}
                          onChange={(model) => {
                            const preset = findCpuPreset(model ?? "")
                            if (preset) {
                              form.setFieldsValue({ cpu_base_mhz: preset.baseMhz, cpu_turbo_mhz: preset.turboMhz })
                            }
                          }}
                        />
                      </Form.Item>
                    </Col>
                    <Col span={4}>
                      <Form.Item label="主频 MHz" name="cpu_base_mhz"><InputNumber min={0} style={{ width: "100%" }} /></Form.Item>
                    </Col>
                    <Col span={4}>
                      <Form.Item label="睿频 MHz" name="cpu_turbo_mhz"><InputNumber min={0} style={{ width: "100%" }} /></Form.Item>
                    </Col>
                  </Row>
                  {matchedPreset && <Alert type="success" showIcon title={`已匹配 CPU 预设：${matchedPreset.family}`} />}
                  <Row gutter={16}>
                    <Col span={8}><Form.Item label="内存" name="memory"><Input placeholder="如 2GB" /></Form.Item></Col>
                    <Col span={8}><Form.Item label="硬盘" name="disk"><Input placeholder="如 40GB NVMe" /></Form.Item></Col>
                    <Col span={8}><Form.Item label="带宽" name="bandwidth"><Input placeholder="如 30Mbps/100Mbps" /></Form.Item></Col>
                  </Row>
                  <Form.Item label="产品卖点" name="features">
                    <Input.TextArea rows={4} placeholder="每行一个卖点，前台展示使用" />
                  </Form.Item>
                  <Form.Item label="标签" name="badges">
                    <Select mode="tags" tokenSeparators={[",", "，"]} placeholder="输入后回车添加标签" />
                  </Form.Item>
                </Space>
              ),
            },
            {
              key: "price",
              label: "定价",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Row gutter={16}>
                    <Col span={6}><Form.Item label="基础展示价" name="base_price"><InputNumber min={0} precision={2} style={{ width: "100%" }} /></Form.Item></Col>
                    <Col span={6}><Form.Item label="基础安装费" name="base_setup_fee"><InputNumber min={0} precision={2} style={{ width: "100%" }} /></Form.Item></Col>
                    <Col span={6}><Form.Item label="库存策略" name="stock_policy"><Select options={STOCK_OPTIONS} /></Form.Item></Col>
                    <Col span={6}><Form.Item label="库存" name="stock"><InputNumber min={0} precision={0} style={{ width: "100%" }} /></Form.Item></Col>
                  </Row>
                  <Row gutter={16}>
                    <Col span={5}><Form.Item label="最小购买数量" name="min_quantity"><InputNumber min={1} precision={0} style={{ width: "100%" }} /></Form.Item></Col>
                    <Col span={5}><Form.Item label="最大购买数量" name="max_quantity"><InputNumber min={0} precision={0} style={{ width: "100%" }} /></Form.Item></Col>
                    <Col span={5}><Form.Item label="排序" name="sort_order"><InputNumber precision={0} style={{ width: "100%" }} /></Form.Item></Col>
                    <Col span={4}><Form.Item label="推荐产品" name="is_featured" valuePropName="checked"><Switch /></Form.Item></Col>
                    <Col span={5}><Form.Item label="购买需实名" name="requires_real_name" valuePropName="checked"><Switch /></Form.Item></Col>
                  </Row>
                  <ProductPricingEditor initialItems={pricingSeed} onChange={handlePricingsChange} />
                </Space>
              ),
            },
            {
              key: "trial",
              label: "试用",
              children: (
                <Row gutter={16}>
                  <Col span={8}><Form.Item label="启用试用" name="trial_enabled" valuePropName="checked"><Switch /></Form.Item></Col>
                  <Col span={8}><Form.Item label="试用天数" name="trial_days"><InputNumber min={0} precision={0} style={{ width: "100%" }} /></Form.Item></Col>
                </Row>
              ),
            },
            {
              key: "provision",
              label: "自动开通",
              children: (
                <Space orientation="vertical" size={16} style={{ width: "100%" }}>
                  <Alert
                    type="info"
                    showIcon
                    title={
                      apiType === "plugin"
                        ? "插件产品会把“上游参数”页签里的产品配置解析为 context.upstream_params，再交给插件开通。"
                        : "自动开通参数来自产品配置；系统镜像来自当前产品组的系统列表。"
                    }
                  />
                  <Row gutter={16}>
                    <Col span={6}><Form.Item label="启用自动开通" name="auto_provision" valuePropName="checked"><Switch /></Form.Item></Col>
                    <Col span={8}><Form.Item label="API 类型" name="api_type"><Select disabled={!autoProvision} options={API_TYPE_OPTIONS} /></Form.Item></Col>
                    {apiType !== "none" && apiType !== "plugin" ? (
                      <Col span={10}><Form.Item label="云接口" name="cloud_server_id"><Select allowClear disabled={!autoProvision} options={cloudServerOptions} /></Form.Item></Col>
                    ) : null}
                  </Row>
                  <Row gutter={16}>
                    <Col span={apiType === "plugin" ? 8 : apiType === "zjmf_finance" ? 16 : 12}>
                      <Form.Item label={apiType === "plugin" ? "开通插件" : apiType === "zjmf_finance" ? "上游产品 ID" : "上游标识"} name="api_identifier">
                        {apiType === "zjmf_finance" ? (
                          <Select
                            allowClear
                            showSearch
                            loading={zjmfProductLoading}
                            disabled={!autoProvision || !cloudServerId}
                            options={zjmfProductOptions}
                            optionFilterProp="label"
                            placeholder="选择魔方财务上游产品"
                            notFoundContent={zjmfProductLoading ? "加载中" : "暂无商品"}
                            onChange={() => setZjmfConfig(null)}
                          />
                        ) : apiType === "plugin" ? (
                          <Select
                            allowClear
                            showSearch
                            loading={pluginLoading}
                            disabled={!autoProvision}
                            options={provisionPluginOptions}
                            optionFilterProp="label"
                            placeholder="选择开通插件"
                            onChange={() => form.setFieldsValue({ provision_interface_id: null })}
                          />
                        ) : (
                          <Input disabled={!autoProvision || apiType === "none"} placeholder="可选：上游标识" />
                        )}
                      </Form.Item>
                    </Col>
                    {apiType === "plugin" && (
                      <Col span={10}>
                        <Form.Item label="开通接口" name="provision_interface_id">
                          <Select
                            allowClear
                            showSearch
                            loading={interfaceLoading}
                            disabled={!autoProvision || !apiIdentifier}
                            options={provisionInterfaceOptions}
                            optionFilterProp="label"
                            placeholder={apiIdentifier ? "选择已创建的开通接口" : "先选择开通插件"}
                            notFoundContent={interfaceLoading ? "加载中" : "暂无接口，请先创建"}
                          />
                        </Form.Item>
                      </Col>
                    )}
                    {apiType === "zjmf_finance" && (
                      <Col span={8}>
                        <Form.Item label="上游同步">
                          <Space.Compact style={{ width: "100%" }}>
                            <Button
                              icon={<CloudDownloadOutlined />}
                              loading={zjmfProductLoading}
                              disabled={!autoProvision || !cloudServerId}
                              onClick={() => void loadZjmfProducts()}
                            >
                              刷新商品
                            </Button>
                            <Button
                              icon={<ApiOutlined />}
                              loading={zjmfConfigLoading}
                              disabled={!autoProvision || !cloudServerId || !apiIdentifier}
                              onClick={() => void loadZjmfConfig()}
                            >
                              预览配置
                            </Button>
                          </Space.Compact>
                        </Form.Item>
                      </Col>
                    )}
                    {apiType === "plugin" && (
                      <Col span={6}>
                        <Form.Item label="插件测试">
                          <Space.Compact style={{ width: "100%" }}>
                            <Button
                              icon={<ApiOutlined />}
                              loading={pluginTesting}
                              disabled={!autoProvision || !apiIdentifier || !provisionInterfaceId}
                              onClick={() => void runPluginTest()}
                            >
                              测试
                            </Button>
                            <Button loading={interfaceLoading} onClick={() => void loadProvisionInterfaces()}>
                              刷新
                            </Button>
                            <Button href="/admin/products/provision-plugins">
                              管理
                            </Button>
                          </Space.Compact>
                        </Form.Item>
                      </Col>
                    )}
                  </Row>
                  {apiType === "zjmf_finance" && (
                    <Alert
                      type={selectedZjmfProduct ? "success" : "info"}
                      showIcon
                      title={
                        selectedZjmfProduct
                          ? `已选择：${selectedZjmfProduct.name}`
                          : "选择魔方财务节点后，可从上游商品列表中绑定 PID"
                      }
                      description={(
                        <Space wrap>
                          {zjmfProductMeta && <Tag>上游商品 {zjmfProductMeta.count}</Tag>}
                          {zjmfProductMeta?.currency && <Tag>{zjmfProductMeta.currency}</Tag>}
                          {selectedZjmfProduct?.group_name && <Tag>{selectedZjmfProduct.group_name}</Tag>}
                          {apiIdentifier && <Tag>PID {apiIdentifier}</Tag>}
                        </Space>
                      )}
                    />
                  )}
                  {apiType === "plugin" && (
                    <Alert
                      type={selectedProvisionPlugin ? "success" : "info"}
                      showIcon
                      title={
                        selectedProvisionPlugin
                          ? `已选择插件：${selectedProvisionPlugin.name}`
                          : "选择开通插件后，商品会使用插件的 provision/manage/test/product_page 标准能力。"
                      }
                      description={
                        selectedProvisionPlugin ? (
                          <Space orientation="vertical" size={6}>
                            <span>{selectedProvisionPlugin.description || "该插件未填写描述。"}</span>
                            <Space wrap>
                              <Tag color={selectedProvisionInterface?.enabled ? "green" : selectedProvisionInterface ? "red" : "orange"}>
                                接口：{selectedProvisionInterface ? selectedProvisionInterface.name : "未选择"}
                              </Tag>
                              {selectedProvisionInterface?.last_test_message ? (
                                <Tag color={selectedProvisionInterface.last_test_ok ? "green" : "red"}>
                                  {selectedProvisionInterface.last_test_message}
                                </Tag>
                              ) : null}
                            </Space>
                            <Space wrap>
                              {(selectedProvisionPlugin.capabilities ?? []).map((item) => <Tag key={item}>{item}</Tag>)}
                              <Tag color="cyan">购买字段 {selectedProvisionPlugin.product_page?.purchase_fields?.length ?? 0}</Tag>
                              <Tag color="geekblue">配置字段 {selectedProvisionPlugin.config_fields?.length ?? 0}</Tag>
                              <Tag color="purple">套餐参数 {selectedProvisionPlugin.upstream_param_fields?.length ?? 0}</Tag>
                            </Space>
                            <Space wrap>
                              {(selectedProvisionPlugin.manage_actions ?? []).map((item) => <Tag key={item.key} color={item.style === "danger" ? "red" : "blue"}>{item.label}</Tag>)}
                            </Space>
                            <Space wrap>
                              {(selectedProvisionPlugin.test_links ?? []).map((item) => (
                                <Tag key={item.url} color="purple">{item.method ?? "GET"} {item.label}</Tag>
                              ))}
                            </Space>
                          </Space>
                        ) : null
                      }
                    />
                  )}
                  {apiType === "plugin" ? (
                    <Space orientation="vertical" size={12} style={{ width: "100%" }}>
                      <Card
                        size="small"
                        title="插件推荐套餐参数"
                        extra={(
                          <Button size="small" type="primary" onClick={applyPluginParamPreset}>
                            一键添加推荐参数
                          </Button>
                        )}
                      >
                        <Table
                          size="small"
                          rowKey={(record) => record.key}
                          columns={pluginRecommendedColumns}
                          dataSource={selectedProvisionPlugin?.upstream_param_fields ?? []}
                          pagination={false}
                          locale={{ emptyText: "该插件未声明推荐套餐参数" }}
                        />
                      </Card>
                      <Card size="small" title="插件上游参数预览">
                        <Table
                          size="small"
                          rowKey={(record) => record.key}
                          columns={pluginParamPreviewColumns}
                          dataSource={pluginParamPreview}
                          pagination={false}
                          locale={{ emptyText: "暂无套餐参数，可点击上方“一键添加推荐参数”" }}
                        />
                      </Card>
                    </Space>
                  ) : null}
                  {apiType === "zjmf_finance" && zjmfConfig && (
                    <Alert
                      type="success"
                      showIcon
                      title={`配置预览：${zjmfConfig.product.name ?? apiIdentifier}`}
                      description={(
                        <Space orientation="vertical" size={8} style={{ width: "100%" }}>
                          <Space wrap>
                            {zjmfStock && <Tag color={zjmfStock.color}>{zjmfStock.label}</Tag>}
                            {truthyFlag(zjmfConfig.product.hidden) && <Tag color="orange">上游隐藏</Tag>}
                            {truthyFlag(zjmfConfig.product.retired) && <Tag color="red">上游停售</Tag>}
                            <Tag>周期 {zjmfConfig.cycles.length}</Tag>
                            <Tag>配置组 {zjmfConfig.config_group_count}</Tag>
                            <Tag>配置项 {zjmfConfig.config_option_count}</Tag>
                            <Tag>子项 {zjmfConfig.sub_option_count}</Tag>
                            <Tag>自定义字段 {zjmfConfig.customfield_count}</Tag>
                          </Space>
                          {zjmfConfig.cycles.length > 0 && (
                            <Space wrap>
                              {zjmfConfig.cycles.slice(0, 8).map((cycle) => (
                                <Tag key={`${cycle.cycle}-${cycle.currency ?? ""}`} color={cycle.price === null ? "default" : undefined}>
                                  {cycle.label} {formatZjmfCyclePrice(cycle)}
                                  {cycle.setup_fee ? ` + ${cycle.setup_fee}` : ""}
                                </Tag>
                              ))}
                            </Space>
                          )}
                          {zjmfConfig.config_groups.slice(0, 4).map((group, groupIndex) => (
                            <div key={group.id ?? group.name ?? `group-${groupIndex}`}>
                              <strong>{group.name || "未命名配置组"}</strong>
                              <div style={{ marginTop: 4 }}>
                                <Space wrap>
                                  {group.options.slice(0, 8).map((option, optionIndex) => (
                                    <Tag key={option.id ?? option.option_name ?? `option-${groupIndex}-${optionIndex}`}>
                                      {option.option_name || "配置项"} × {option.sub_count}
                                    </Tag>
                                  ))}
                                </Space>
                              </div>
                            </div>
                          ))}
                          {zjmfConfig.customfields.length > 0 && (
                            <Space wrap>
                              {zjmfConfig.customfields.slice(0, 8).map((field, fieldIndex) => (
                                <Tag key={field.id ?? field.fieldname ?? `field-${fieldIndex}`}>
                                  {field.fieldname || "自定义字段"}{field.required ? " 必填" : ""}
                                </Tag>
                              ))}
                            </Space>
                          )}
                        </Space>
                      )}
                    />
                  )}
                  <Space wrap>
                    <Button icon={<SettingOutlined />} onClick={applySpecFields}>
                      {apiType === "plugin" ? "从规格生成上游参数" : "从详情规格生成字段"}
                    </Button>
                    {apiType !== "plugin" && apiType !== "zjmf_finance" ? (
                      <Button type="primary" icon={<ApiOutlined />} onClick={applyDcimPreset}>套用魔方云预设</Button>
                    ) : null}
                  </Space>
                </Space>
              ),
            },
            {
              key: "config",
              label: apiType === "plugin" ? "上游参数" : "产品配置",
              children: (
                <ProductConfigFieldsEditor initialItems={configSeed} onChange={handleConfigFieldsChange} mode={apiType === "plugin" ? "plugin" : "default"} />
              ),
            },
            {
              key: "os",
              label: "系统管理",
              children: <ProductOsOptionsEditor currentGroup={currentGroup} cloudServerId={cloudServerId} productConfig={configSeed} />,
            },
          ]}
        />
      </Form>
    </Card>
  )
}
