import { useEffect, useMemo, useState } from "react"
import {
  ApartmentOutlined,
  DeleteOutlined,
  DownOutlined,
  FolderOpenOutlined,
  GlobalOutlined,
  PlusOutlined,
  RightOutlined,
  TagsOutlined,
} from "@ant-design/icons"
import { Button, Divider, Form, Input, InputNumber, Modal, Select, Space, Switch, Typography } from "antd"
import { toast } from "../../utils/toast"
import { ICON_CATALOG } from "./iconsCatalog"
import { NETWORK_TYPES } from "./networkTypes"
import {
  createGroup,
  deleteGroup,
  updateGroup,
  type OsOption,
  type ProductCategory,
  type ProductGroupCreatePayload,
  type ProductGroup,
} from "../api/product_catalog"

interface Props {
  open: boolean
  onClose: () => void
  onSaved: () => void
  categories: ProductCategory[]
  initial?: ProductGroup | null
  defaultCategoryId?: number | null
}

interface GroupFormValues {
  category_id: number
  slug: string
  name: string
  headline?: string
  description?: string
  icon?: string
  network_type?: string
  sort_order?: number
  requires_real_name?: boolean
  area?: number | null
  node?: number | null
  os_options?: OsOption[]
}

const { Text } = Typography

const iconOptions = ICON_CATALOG.map((item) => ({
  value: item.name,
  label: `${item.label} · ${item.name}`,
}))

const networkOptions = NETWORK_TYPES.map((item) => ({
  value: item.value,
  label: item.description ? `${item.label} · ${item.description}` : item.label,
}))

export default function ProductGroupFormModal({
  open,
  onClose,
  onSaved,
  categories,
  initial,
  defaultCategoryId,
}: Props) {
  const [form] = Form.useForm<GroupFormValues>()
  const [osExpanded, setOsExpanded] = useState(false)
  const [osTouched, setOsTouched] = useState(false)
  const isEdit = !!initial
  const watchedOsOptions = Form.useWatch("os_options", form)

  const categoryOptions = useMemo(
    () => categories.map((category) => ({ value: category.id, label: `${category.name} · ${category.slug}` })),
    [categories],
  )

  useEffect(() => {
    if (!open) return
    setOsExpanded(false)
    setOsTouched(false)
    form.setFieldsValue({
      category_id: initial?.category_id ?? defaultCategoryId ?? categories[0]?.id,
      slug: initial?.slug ?? "",
      name: initial?.name ?? "",
      headline: initial?.headline ?? "",
      description: initial?.description ?? "",
      icon: initial?.icon ?? undefined,
      network_type: initial?.network_type ?? undefined,
      sort_order: initial?.sort_order ?? 0,
      requires_real_name: initial?.requires_real_name ?? false,
      area: initial?.area ?? null,
      node: initial?.node ?? null,
      os_options: initial?.os_options ?? [],
    })
  }, [categories, defaultCategoryId, form, initial, open])

  const osCount = useMemo(() => {
    const items = Array.isArray(watchedOsOptions)
      ? watchedOsOptions
      : initial?.os_options ?? []
    return items.filter((item) => item?.label || item?.value).length
  }, [initial?.os_options, watchedOsOptions])

  const submit = async () => {
    try {
      const values = await form.validateFields()
      const osOptions = (values.os_options ?? [])
        .filter((item) => item?.label || item?.value)
        .map((item) => ({ label: item.label?.trim() ?? "", value: Number(item.value) || 0 }))

      const payload: Omit<ProductGroupCreatePayload, "slug"> = {
        category_id: values.category_id,
        name: values.name.trim(),
        headline: values.headline?.trim() || null,
        description: values.description?.trim() || null,
        icon: values.icon || null,
        network_type: values.network_type || null,
        sort_order: values.sort_order ?? 0,
        requires_real_name: !!values.requires_real_name,
        area: values.area ?? null,
        node: values.node ?? null,
      }
      if (!isEdit || osTouched) {
        payload.os_options = osOptions
      }

      if (isEdit && initial) {
        await updateGroup(initial.id, payload)
        toast.success("已保存")
      } else {
        await createGroup({ ...payload, slug: values.slug.trim() })
        toast.success("已添加")
      }
      onSaved()
      onClose()
    } catch (e: unknown) {
      if ((e as { errorFields?: unknown[] })?.errorFields) return
      const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      toast.error(detail || "保存失败")
    }
  }

  const remove = () => {
    if (!initial) return
    Modal.confirm({
      title: `删除产品组「${initial.name}」？`,
      content: "删除后不可恢复，关联产品可能需要先调整所属产品组。",
      okText: "删除",
      okButtonProps: { danger: true },
      cancelText: "取消",
      async onOk() {
        try {
          await deleteGroup(initial.id)
          toast.success("已删除")
          onSaved()
          onClose()
        } catch (e: unknown) {
          const detail = (e as { response?: { data?: { detail?: string } } })?.response?.data?.detail
          toast.error(detail || "删除失败")
        }
      },
    })
  }

  return (
    <Modal
      open={open}
      title={
        <Space>
          <TagsOutlined />
          {isEdit ? "编辑产品组" : "添加产品组"}
        </Space>
      }
      width={720}
      destroyOnHidden
      onCancel={onClose}
      onOk={submit}
      okText={isEdit ? "保存" : "添加"}
      cancelText="取消"
      footer={(_, { OkBtn, CancelBtn }) => (
        <Space style={{ width: "100%", justifyContent: "space-between" }}>
          {isEdit ? (
            <Button danger type="text" icon={<DeleteOutlined />} onClick={remove}>
              删除
            </Button>
          ) : (
            <Text type="secondary" style={{ fontSize: 12 }}>产品组用于承载同一线路或同一地区的 SKU</Text>
          )}
          <Space>
            <CancelBtn />
            <OkBtn />
          </Space>
        </Space>
      )}
    >
      <Form
        form={form}
        layout="vertical"
        requiredMark="optional"
        onValuesChange={(changed) => {
          if (Object.prototype.hasOwnProperty.call(changed, "os_options")) {
            setOsTouched(true)
          }
        }}
      >
        <Form.Item
          label="所属分类"
          name="category_id"
          rules={[{ required: true, message: "请选择分类" }]}
        >
          <Select
            showSearch
            placeholder="请选择分类"
            options={categoryOptions}
            optionFilterProp="label"
            prefix={<FolderOpenOutlined />}
          />
        </Form.Item>

        <Space align="start" size={16} style={{ width: "100%" }}>
          <Form.Item
            label="slug"
            name="slug"
            rules={[{ required: !isEdit, message: "请填写 slug" }]}
            style={{ flex: 1 }}
          >
            <Input disabled={isEdit} placeholder="hk-cn2" />
          </Form.Item>
          <Form.Item
            label="名称"
            name="name"
            rules={[{ required: true, message: "请填写名称" }]}
            style={{ flex: 1 }}
          >
            <Input placeholder="香港 CN2" />
          </Form.Item>
        </Space>

        <Form.Item label="一句话卖点" name="headline">
          <Input placeholder="低延迟回国线路，三网直连" />
        </Form.Item>

        <Form.Item label="详细描述" name="description">
          <Input.TextArea rows={3} placeholder="用于前台展示或后台备注" />
        </Form.Item>

        <Space align="start" size={16} style={{ width: "100%" }}>
          <Form.Item label="图标" name="icon" style={{ flex: 1 }}>
            <Select
              allowClear
              showSearch
              placeholder="选择图标"
              options={iconOptions}
              optionFilterProp="label"
            />
          </Form.Item>
          <Form.Item label="网络类型" name="network_type" style={{ flex: 1 }}>
            <Select
              allowClear
              showSearch
              placeholder="未指定"
              options={networkOptions}
              optionFilterProp="label"
              prefix={<GlobalOutlined />}
            />
          </Form.Item>
          <Form.Item label="排序" name="sort_order" style={{ width: 120 }}>
            <InputNumber min={0} precision={0} style={{ width: "100%" }} />
          </Form.Item>
          <Form.Item label="购买需实名" name="requires_real_name" valuePropName="checked" style={{ width: 120 }}>
            <Switch />
          </Form.Item>
        </Space>

        <Divider plain>
          <Space><ApartmentOutlined /> 上游配置</Space>
        </Divider>

        <Space align="start" size={16} style={{ width: "100%" }}>
          <Form.Item label="区域 ID" name="area" style={{ flex: 1 }}>
            <InputNumber min={0} precision={0} placeholder="留空则不指定" style={{ width: "100%" }} />
          </Form.Item>
          <Form.Item label="节点 ID" name="node" style={{ flex: 1 }}>
            <InputNumber min={0} precision={0} placeholder="留空则不指定" style={{ width: "100%" }} />
          </Form.Item>
        </Space>

        <Divider plain>操作系统列表</Divider>

        <Button
          block
          type="dashed"
          icon={osExpanded ? <DownOutlined /> : <RightOutlined />}
          onClick={() => setOsExpanded((value) => !value)}
        >
          {osExpanded ? "收起操作系统" : `展开操作系统（${osCount} 个）`}
        </Button>

        {osExpanded && (
          <Form.List name="os_options">
            {(fields, { add, remove }) => (
              <Space orientation="vertical" size={10} style={{ width: "100%", marginTop: 12 }}>
                {fields.map((field) => (
                  <Space key={field.key} align="baseline" style={{ width: "100%" }}>
                    <Form.Item
                      {...field}
                      name={[field.name, "label"]}
                      rules={[{ required: true, message: "请填写系统名称" }]}
                      style={{ flex: 1, marginBottom: 0 }}
                    >
                      <Input placeholder="Debian 12 64位" />
                    </Form.Item>
                    <Form.Item
                      {...field}
                      name={[field.name, "value"]}
                      rules={[{ required: true, message: "请填写 OS ID" }]}
                      style={{ width: 160, marginBottom: 0 }}
                    >
                      <InputNumber min={0} precision={0} placeholder="OS ID" style={{ width: "100%" }} />
                    </Form.Item>
                    <Button
                      danger
                      type="text"
                      icon={<DeleteOutlined />}
                      onClick={() => {
                        setOsTouched(true)
                        remove(field.name)
                      }}
                    />
                  </Space>
                ))}

                <Button
                  block
                  icon={<PlusOutlined />}
                  onClick={() => {
                    setOsTouched(true)
                    add({ label: "", value: 0 })
                  }}
                >
                  添加操作系统
                </Button>
              </Space>
            )}
          </Form.List>
        )}
      </Form>
    </Modal>
  )
}
