import { useCallback, useEffect, useState } from "react"
import {
  Button,
  Card,
  Col,
  Empty,
  Input,
  InputNumber,
  Popover,
  Row,
  Select,
  Space,
  Spin,
  Statistic,
  Switch,
  Table,
  Tabs,
  Tag,
  Tooltip,
  Typography,
  message,
} from "antd"
import type { ColumnsType } from "antd/es/table"
import { GiftOutlined } from "@ant-design/icons"
import {
  claimMallCoupon,
  getMallItems,
  getMyMallClaims,
  getPromotionOverview,
  type MallClaimRecord,
  type MallCouponItem,
  type PromotionOverview,
} from "../api/promotion"
import { formatPoints, formatYuan } from "../utils/format"

const { Text, Title } = Typography

function couponAmount(coupon: { type: string; value: number; threshold_amount: number; max_discount_amount: number }) {
  if (coupon.type === "fixed") return `立减 ${formatYuan(coupon.value)}`
  if (coupon.type === "threshold_fixed") return `满 ${formatYuan(coupon.threshold_amount)} 减 ${formatYuan(coupon.value)}`
  if (coupon.type === "percent") return `${coupon.value / 10} 折`
  return formatYuan(coupon.value)
}

function formatDate(value: string | null) {
  return value ? new Date(value).toLocaleString() : "无期限"
}

function claimStatusLabel(status: string) {
  if (status === "claimed") return "未使用"
  if (status === "used") return "已使用"
  if (status === "expired") return "已过期"
  return status
}

type CouponDetailData = Pick<
  MallCouponItem,
  | "description"
  | "type"
  | "value"
  | "threshold_amount"
  | "max_discount_amount"
  | "scope"
  | "category"
  | "stock_remaining"
  | "max_claims_per_user"
  | "max_claims_per_user_per_day"
  | "required_member_level"
  | "required_member_level_name"
  | "expires_at"
  | "issuer_name"
>

function couponDetailContent(item: CouponDetailData) {
  return (
    <Space orientation="vertical" size={4} style={{ maxWidth: 280 }}>
      {item.description && <Text>{item.description}</Text>}
      <Text type="secondary" style={{ fontSize: 12 }}>类型：{couponAmount(item)}</Text>
      <Text type="secondary" style={{ fontSize: 12 }}>范围：{item.scope === "public" ? "全站公开" : "代理专区"}</Text>
      {item.category && <Text type="secondary" style={{ fontSize: 12 }}>分类：{item.category}</Text>}
      <Text type="secondary" style={{ fontSize: 12 }}>库存：{item.stock_remaining}</Text>
      {item.max_claims_per_user > 0 && <Text type="secondary" style={{ fontSize: 12 }}>每用户限领：{item.max_claims_per_user} 张</Text>}
      {item.max_claims_per_user_per_day > 0 && <Text type="secondary" style={{ fontSize: 12 }}>每日限领：{item.max_claims_per_user_per_day} 张</Text>}
      {item.required_member_level > 0 && <Text type="secondary" style={{ fontSize: 12 }}>需会员等级：{item.required_member_level_name || `LV${item.required_member_level}`}</Text>}
      <Text type="secondary" style={{ fontSize: 12 }}>有效期：{formatDate(item.expires_at)}</Text>
    </Space>
  )
}

function itemDisabledReason(
  item: MallCouponItem,
  myClaims: MallClaimRecord[],
  memberLevel: number,
): string | null {
  if (item.stock_remaining <= 0) return "已领完"
  const claimedCount = myClaims.filter((c) => c.mall_item_id === item.id && c.status === "claimed").length
  if (item.max_claims_per_user > 0 && claimedCount >= item.max_claims_per_user) return "已达到领取上限"
  if (item.required_member_level > 0 && memberLevel < item.required_member_level) {
    return `仅限 ${item.required_member_level_name || `LV${item.required_member_level}`} 及以上会员`
  }
  return null
}

export default function PointsMall() {
  const [loading, setLoading] = useState(true)
  const [overview, setOverview] = useState<PromotionOverview | null>(null)
  const [items, setItems] = useState<MallCouponItem[]>([])
  const [myClaims, setMyClaims] = useState<MallClaimRecord[]>([])
  const [claimingId, setClaimingId] = useState<number | null>(null)
  const [scope, setScope] = useState<"public" | "agent_subordinates">("public")
  const [query, setQuery] = useState("")
  const [couponType, setCouponType] = useState<"fixed" | "threshold_fixed" | "percent" | undefined>(undefined)
  const [minPoints, setMinPoints] = useState<number | undefined>(undefined)
  const [maxPoints, setMaxPoints] = useState<number | undefined>(undefined)
  const [onlyHot, setOnlyHot] = useState(false)
  const [sortBy, setSortBy] = useState<"points" | "expires" | "sort_order">("sort_order")

  const loadData = useCallback(async () => {
    setLoading(true)
    try {
      const [ov, res, claimsRes] = await Promise.all([
        getPromotionOverview().catch(() => null),
        getMallItems({
          limit: 100,
          offset: 0,
          scope,
          q: query.trim() || undefined,
          type: couponType,
          min_points: minPoints,
          max_points: maxPoints,
          is_hot: onlyHot || undefined,
          sort_by: sortBy,
        }),
        getMyMallClaims(),
      ])
      setOverview(ov)
      setItems(res.items)
      setMyClaims(claimsRes.items)
    } catch (error) {
      const detail = (error as { response?: { data?: { detail?: string } } })?.response?.data?.detail
      message.error(detail || "加载积分商城失败")
    } finally {
      setLoading(false)
    }
  }, [scope, query, couponType, minPoints, maxPoints, onlyHot, sortBy])

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

  const handleClaim = async (item: MallCouponItem) => {
    try {
      setClaimingId(item.id)
      const { verifyCaptcha } = await import("../utils/geetest")
      const captcha = await verifyCaptcha()
      const data = await claimMallCoupon(item.id, captcha)
      setMyClaims((prev) => [
        ...prev,
        {
          id: data.claim_id,
          mall_item_id: item.id,
          promo_code_id: item.promo_code_id,
          title: item.title || item.description || null,
          subtitle: item.subtitle ?? null,
          cover_image: item.cover_image ?? null,
          description: (item.description || item.title) ?? null,
          category: item.category ?? null,
          points_price: item.points_price,
          stock_remaining: item.stock_remaining - 1,
          scope: item.scope,
          max_claims_per_user: item.max_claims_per_user,
          max_claims_per_user_per_day: item.max_claims_per_user_per_day,
          required_member_level: item.required_member_level,
          required_member_level_name: item.required_member_level_name ?? null,
          is_hot: item.is_hot,
          issuer_name: item.issuer_name || "平台",
          points_paid: data.points_paid,
          status: "claimed",
          used_at: null,
          order_id: null,
          type: item.type,
          value: item.value,
          threshold_amount: item.threshold_amount,
          max_discount_amount: item.max_discount_amount,
          expires_at: item.expires_at,
        },
      ])
      setItems((prev) => prev.map((it) => (it.id === item.id ? { ...it, stock_remaining: it.stock_remaining - 1, claimed: true } : it)))
      setOverview((prev) => prev ? { ...prev, available_points: data.available_points } : prev)
      message.success("优惠券领取成功")
    } catch (error) {
      const msg = (error as Error)?.message || "领取失败"
      if (msg === "已取消人机验证") return
      message.error(msg)
    } finally {
      setClaimingId(null)
    }
  }

  const claimColumns: ColumnsType<MallClaimRecord> = [
    {
      title: "优惠券",
      render: (_, record) => {
        const name = record.title || record.description || "优惠券"
        return (
          <Popover
            content={couponDetailContent(record)}
            title={name}
            trigger="hover"
            placement="topLeft"
          >
            <Text strong className="cursor-pointer">{name}</Text>
          </Popover>
        )
      },
    },
    { title: "优惠", render: (_, record) => <Tag>{couponAmount(record)}</Tag> },
    { title: "支付积分", dataIndex: "points_paid", render: (value: number) => formatPoints(value) },
    { title: "状态", dataIndex: "status", render: (value: string) => <Tag>{claimStatusLabel(value)}</Tag> },
    { title: "有效期", dataIndex: "expires_at", render: formatDate },
  ]

  if (loading) {
    return <Spin size="large" description="加载积分商城" style={{ display: "flex", justifyContent: "center", padding: 80 }} />
  }

  return (
    <Space orientation="vertical" size={20} style={{ width: "100%" }}>
      <div>
        <Title level={3} style={{ marginBottom: 4 }}>积分商城</Title>
        <Text type="secondary">使用积分兑换优惠券，可在购买或续费服务时使用。</Text>
      </div>

      <Row gutter={[16, 16]}>
        <Col xs={24} md={12}>
          <Card variant="outlined">
            <Statistic title="可用积分" value={formatPoints(overview?.available_points ?? 0)} prefix={<GiftOutlined />} />
          </Card>
        </Col>
        <Col xs={24} md={12}>
          <Card variant="outlined">
            <Statistic title="我的券数" value={myClaims.filter((c) => c.status === "claimed").length} prefix={<GiftOutlined />} />
          </Card>
        </Col>
      </Row>

      <Row gutter={[12, 12]} align="middle">
        <Col xs={24} md={8}>
          <Input.Search
            placeholder="搜索标题/描述/分类/发行者"
            allowClear
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onSearch={() => void loadData()}
          />
        </Col>
        <Col xs={12} md={4}>
          <Select
            placeholder="优惠类型"
            allowClear
            style={{ width: "100%" }}
            value={couponType}
            onChange={setCouponType}
            options={[
              { value: "fixed", label: "立减" },
              { value: "threshold_fixed", label: "满减" },
              { value: "percent", label: "折扣" },
            ]}
          />
        </Col>
        <Col xs={12} md={8}>
          <Space>
            <InputNumber min={0} precision={0} placeholder="最低积分" value={minPoints} onChange={(v) => setMinPoints(v ?? undefined)} style={{ width: 110 }} />
            <Text>-</Text>
            <InputNumber min={0} precision={0} placeholder="最高积分" value={maxPoints} onChange={(v) => setMaxPoints(v ?? undefined)} style={{ width: 110 }} />
          </Space>
        </Col>
        <Col xs={12} md={4}>
          <Select
            style={{ width: "100%" }}
            value={sortBy}
            onChange={setSortBy}
            options={[
              { value: "sort_order", label: "默认排序" },
              { value: "points", label: "积分从低到高" },
              { value: "expires", label: "有效期最近" },
            ]}
          />
        </Col>
        <Col xs={12} md={4}>
          <Space>
            <Switch checked={onlyHot} onChange={setOnlyHot} />
            <Text>仅看热门</Text>
          </Space>
        </Col>
      </Row>

      <Card
        variant="outlined"
        title={
          <Tabs
            activeKey={scope}
            onChange={(key) => setScope(key as "public" | "agent_subordinates")}
            items={[
              { key: "public", label: "积分商城" },
              { key: "agent_subordinates", label: "代理专区" },
            ]}
          />
        }
      >
        {items.length === 0 ? (
          <Empty description="暂无可兑换优惠券" />
        ) : (
          <Row gutter={[16, 16]}>
            {items.map((item) => {
              const disabledReason = itemDisabledReason(item, myClaims, overview?.member_level ?? 0)
              return (
                <Col xs={24} sm={12} lg={8} xl={6} key={item.id}>
                  <Popover
                    content={couponDetailContent(item)}
                    title={item.title || "优惠券详情"}
                    trigger="hover"
                    placement="topLeft"
                  >
                    <Card
                      hoverable
                      variant="outlined"
                      cover={item.cover_image ? <img alt={item.title || "优惠券"} src={item.cover_image} style={{ height: 140, objectFit: "cover" }} /> : null}
                    >
                      <Space orientation="vertical" size={8} style={{ width: "100%" }}>
                        <Space wrap>
                          <Text strong>{item.title || "优惠券"}</Text>
                          {item.is_hot && <Tag color="red">HOT</Tag>}
                        </Space>
                        {item.subtitle ? <Text type="secondary" style={{ fontSize: 12 }}>{item.subtitle}</Text> : null}
                        <Tag>{couponAmount(item)}</Tag>
                        <Space wrap size={4}>
                          {item.max_claims_per_user > 0 && <Tag color="blue">限{item.max_claims_per_user}张</Tag>}
                          {item.max_claims_per_user_per_day > 0 && <Tag color="cyan">每日{item.max_claims_per_user_per_day}张</Tag>}
                          {item.required_member_level > 0 && <Tag color="purple">需{item.required_member_level_name || `LV${item.required_member_level}`}</Tag>}
                        </Space>
                        <Text type="secondary" style={{ fontSize: 12 }}>发行：{item.issuer_name || "平台"}</Text>
                        <Text type="secondary" style={{ fontSize: 12 }}>库存：{item.stock_remaining}</Text>
                        <Text type="secondary" style={{ fontSize: 12 }}>有效期：{formatDate(item.expires_at)}</Text>
                        <Tooltip title={disabledReason || ""}>
                          <Button
                            type="primary"
                            size="small"
                            block
                            loading={claimingId === item.id}
                            disabled={!!disabledReason || item.claimed || item.stock_remaining <= 0}
                            onClick={() => handleClaim(item)}
                          >
                            {item.claimed ? "已领取" : `${formatPoints(item.points_price)} 积分领取`}
                          </Button>
                        </Tooltip>
                      </Space>
                    </Card>
                  </Popover>
                </Col>
              )
            })}
          </Row>
        )}
      </Card>

      {myClaims.length > 0 && (
        <Card variant="outlined" title="我的券包">
          <Table<MallClaimRecord>
            rowKey="id"
            size="small"
            dataSource={myClaims}
            pagination={false}
            columns={claimColumns}
          />
        </Card>
      )}
    </Space>
  )
}
