import { useState, useCallback, useMemo } from 'react';
import {
  Table,
  Button,
  Space,
  Modal,
  Form,
  Input,
  InputNumber,
  Select,
  Tag,
  Badge,
  Switch,
  Upload,
  message,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  PictureOutlined,
  UploadOutlined,
} from '@ant-design/icons';
import {
  pointsApi,
  type PointsProduct,
  type CreatePointsProductReq,
} from '../../api/health/points';
import { AuthButton } from '../../components/AuthButton';
import { DrawerForm } from '../../components/DrawerForm';
import type { FormSection } from '../../components/DrawerForm';
import MediaPicker from '../../components/MediaPicker';
import { PageContainer } from '../../components/PageContainer';
import { uploadFile } from '../../api/upload';
import { usePaginatedData } from '../../hooks/usePaginatedData';
import { useThemeMode } from '../../hooks/useThemeMode';
import { formatDateTime } from '../../utils/format';

/** 商品类型映射 */
const PRODUCT_TYPES: Record<string, string> = {
  physical: '实物',
  service: '服务券',
  privilege: '权益',
};

/** 商品类型选项 */
const PRODUCT_TYPE_OPTIONS = Object.entries(PRODUCT_TYPES).map(([value, label]) => ({
  value,
  label,
}));

/** 商品类型颜色映射 */
const PRODUCT_TYPE_COLORS: Record<string, string> = {
  physical: 'blue',
  service: 'green',
  privilege: 'purple',
};

interface ProductFilters {
  search: string;
  product_type: string | undefined;
  is_active: string | undefined;
}

export default function PointsProductList() {
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<PointsProduct | null>(null);
  const [mediaPickerOpen, setMediaPickerOpen] = useState(false);
  const [imageUrl, setImageUrl] = useState<string>('');
  const isDark = useThemeMode();

  const fetchProducts = useCallback(
    async (page: number, pageSize: number, filters: ProductFilters) => {
      const result = await pointsApi.listProducts({
        page,
        page_size: pageSize,
        product_type: filters.product_type || undefined,
        keyword: filters.search || undefined,
      });
      let filtered = result.data;
      if (filters.is_active !== undefined) {
        const isActive = filters.is_active === 'true';
        filtered = filtered.filter((p) => p.is_active === isActive);
      }
      return { data: filtered, total: result.total };
    },
    [],
  );

  const {
    data,
    total,
    page,
    loading,
    filters,
    setFilters,
    refresh,
  } = usePaginatedData<PointsProduct, ProductFilters>(
    fetchProducts,
    { pageSize: 20, defaultFilters: { search: '', product_type: undefined, is_active: undefined } },
  );

  // ---- 新建 / 编辑 ----
  const openCreate = () => {
    setEditing(null);
    setImageUrl('');
    setModalOpen(true);
  };

  const openEdit = (record: PointsProduct) => {
    setEditing(record);
    setImageUrl(record.image_url || '');
    setModalOpen(true);
  };

  const handleCloseDrawer = () => {
    setModalOpen(false);
    setEditing(null);
  };

  const handleSubmit = async (values: Record<string, unknown>) => {
    try {
      const typed = values as {
        name: string;
        product_type: string;
        points_cost: number;
        stock: number;
        description?: string;
        sort_order?: number;
      };
      // 保存时去掉 URL 中的 ?token= 参数（token 是临时的，不应持久化）
      const cleanImageUrl = imageUrl ? imageUrl.replace(/\?token=.*$/, '') : undefined;
      if (editing) {
        await pointsApi.updateProduct(editing.id, {
          ...typed,
          image_url: cleanImageUrl,
          version: editing.version,
        });
      } else {
        const req: CreatePointsProductReq = {
          name: typed.name,
          product_type: typed.product_type,
          points_cost: typed.points_cost,
          stock: typed.stock,
          description: typed.description,
          image_url: cleanImageUrl,
          sort_order: typed.sort_order,
        };
        await pointsApi.createProduct(req);
      }
      message.success(editing ? '更新成功' : '创建成功');
      handleCloseDrawer();
      refresh(page);
    } catch (err: unknown) {
      const apiMsg = (err as { response?: { data?: { message?: string } } })?.response?.data?.message;
      message.error(apiMsg || (editing ? '更新失败' : '创建失败'));
    }
  };

  // ---- 切换上下架 ----
  const handleToggleActive = async (record: PointsProduct) => {
    try {
      await pointsApi.updateProduct(record.id, {
        is_active: !record.is_active,
        version: record.version,
      });
      message.success(record.is_active ? '已下架' : '已上架');
      refresh(page);
    } catch {
      message.error('操作失败');
    }
  };

  // ---- 删除 ----
  const handleDelete = (record: PointsProduct) => {
    Modal.confirm({
      title: '确认删除',
      content: `确定要删除商品「${record.name}」吗？`,
      okType: 'danger',
      onOk: async () => {
        try {
          await pointsApi.deleteProduct(record.id, record.version);
          message.success('删除成功');
          refresh(page);
        } catch {
          message.error('删除失败');
        }
      },
    });
  };

  const resetFilters = () => {
    setFilters({ search: '', product_type: undefined, is_active: undefined });
  };

  // ---- 列定义 ----
  const columns = useMemo(() => [
    {
      title: '商品名称',
      dataIndex: 'name',
      key: 'name',
      width: 160,
    },
    {
      title: '类型',
      dataIndex: 'product_type',
      key: 'product_type',
      width: 100,
      render: (val: string) => (
        <Tag color={PRODUCT_TYPE_COLORS[val] || 'default'}>
          {PRODUCT_TYPES[val] || val}
        </Tag>
      ),
    },
    {
      title: '积分',
      dataIndex: 'points_cost',
      key: 'points_cost',
      width: 90,
      render: (val: number) => <span style={{ fontWeight: 600, color: '#d97706' }}>{val}</span>,
    },
    {
      title: '库存',
      dataIndex: 'stock',
      key: 'stock',
      width: 90,
      render: (val: number) => (val === -1 ? <Tag color="cyan">无限</Tag> : val),
    },
    {
      title: '排序',
      dataIndex: 'sort_order',
      key: 'sort_order',
      width: 70,
      render: (val: number) => val ?? 0,
    },
    {
      title: '状态',
      dataIndex: 'is_active',
      key: 'is_active',
      width: 80,
      render: (val: boolean) => (
        <Badge status={val ? 'success' : 'default'} text={val ? '上架' : '下架'} />
      ),
    },
    {
      title: '更新时间',
      dataIndex: 'updated_at',
      key: 'updated_at',
      width: 170,
      render: (val: string) => formatDateTime(val),
    },
    {
      title: '操作',
      key: 'action',
      width: 140,
      render: (_: unknown, record: PointsProduct) => (
        <AuthButton code="health.points.manage">
          <Space size="small">
            <Button
              type="link"
              size="small"
              icon={<EditOutlined />}
              onClick={() => openEdit(record)}
            >
              编辑
            </Button>
            <Switch
              size="small"
              checked={record.is_active}
              checkedChildren="上架"
              unCheckedChildren="下架"
              onChange={() => handleToggleActive(record)}
            />
            <Button
              type="link"
              size="small"
              danger
              icon={<DeleteOutlined />}
              onClick={() => handleDelete(record)}
            >
              删除
            </Button>
          </Space>
        </AuthButton>
      ),
    },
  ], [openEdit, handleToggleActive, handleDelete]);

  /** 抽屉表单分区 */
  const formSections: FormSection[] = [
    {
      title: '基本信息',
      fields: (
        <>
          <Form.Item
            name="name"
            label="商品名称"
            rules={[{ required: true, message: '请输入商品名称' }]}
          >
            <Input placeholder="如：体检套餐兑换券" />
          </Form.Item>
          <Form.Item
            name="product_type"
            label="商品类型"
            rules={[{ required: true, message: '请选择商品类型' }]}
          >
            <Select placeholder="选择类型" options={PRODUCT_TYPE_OPTIONS} />
          </Form.Item>
          <Form.Item
            name="points_cost"
            label="所需积分"
            rules={[{ required: true, message: '请输入所需积分' }]}
          >
            <InputNumber min={1} max={999999} style={{ width: '100%' }} placeholder="如：100" />
          </Form.Item>
          <Form.Item name="stock" label="库存数量">
            <InputNumber min={-1} max={999999} style={{ width: '100%' }} placeholder="-1 表示无限" />
          </Form.Item>
        </>
      ),
    },
    {
      title: '展示设置',
      fields: (
        <>
          <Form.Item label="商品图片">
            <Space.Compact style={{ width: '100%' }}>
              <Input
                value={imageUrl}
                onChange={(e) => setImageUrl(e.target.value)}
                placeholder="输入 URL 或从媒体库选择"
                style={{ flex: 1 }}
              />
              <Button icon={<PictureOutlined />} onClick={() => setMediaPickerOpen(true)}>
                媒体库
              </Button>
              <Upload
                accept="image/*"
                showUploadList={false}
                beforeUpload={async (file) => {
                  try {
                    const result = await uploadFile(file);
                    setImageUrl(result.url);
                    message.success('图片上传成功');
                  } catch {
                    message.error('图片上传失败');
                  }
                  return false;
                }}
              >
                <Button icon={<UploadOutlined />}>上传</Button>
              </Upload>
            </Space.Compact>
            {imageUrl && (
              <div
                style={{
                  marginTop: 8,
                  borderRadius: 8,
                  overflow: 'hidden',
                  border: `1px solid ${isDark ? '#1e293b' : '#e2e8f0'}`,
                }}
              >
                <img
                  src={imageUrl}
                  alt="商品图片预览"
                  style={{ width: '100%', height: 120, objectFit: 'cover' }}
                  onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}
                />
              </div>
            )}
          </Form.Item>
          <Form.Item name="sort_order" label="排序">
            <InputNumber min={0} max={9999} style={{ width: '100%' }} placeholder="0" />
          </Form.Item>
          <Form.Item name="description" label="描述">
            <Input.TextArea rows={3} placeholder="商品说明" />
          </Form.Item>
        </>
      ),
    },
  ];

  return (
    <PageContainer
      title="积分商品"
      filters={
        <>
          <Input
            placeholder="搜索商品名称"
            value={filters.search}
            onChange={(e) => setFilters((f) => ({ ...f, search: e.target.value }))}
            allowClear
            style={{ width: 200 }}
          />
          <Select
            placeholder="筛选类型"
            value={filters.product_type}
            onChange={(val) => setFilters((f) => ({ ...f, product_type: val }))}
            options={PRODUCT_TYPE_OPTIONS}
            allowClear
            style={{ width: 140 }}
          />
          <Select
            placeholder="筛选状态"
            value={filters.is_active}
            onChange={(val) => setFilters((f) => ({ ...f, is_active: val }))}
            options={[
              { value: 'true', label: '上架' },
              { value: 'false', label: '下架' },
            ]}
            allowClear
            style={{ width: 120 }}
          />
        </>
      }
      onResetFilters={resetFilters}
      actions={
        <AuthButton code="health.points.manage">
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            新建商品
          </Button>
        </AuthButton>
      }
    >
      <Table
        rowKey="id"
        columns={columns}
        dataSource={data}
        loading={loading}
        scroll={{ x: 900 }}
        pagination={{
          current: page,
          pageSize: 20,
          total,
          showSizeChanger: true,
          showTotal: (t) => `共 ${t} 条`,
          onChange: (p) => refresh(p),
        }}
      />

      {/* 新建 / 编辑抽屉 */}
      <DrawerForm
        title={editing ? '编辑商品' : '新建商品'}
        open={modalOpen}
        onClose={handleCloseDrawer}
        onSubmit={handleSubmit}
        initialValues={editing
          ? {
              name: editing.name,
              product_type: editing.product_type,
              points_cost: editing.points_cost,
              stock: editing.stock,
              description: editing.description,
              sort_order: editing.sort_order,
            }
          : { stock: -1, sort_order: 0 }}
        loading={false}
        width={600}
        columns={2}
        sections={formSections}
      />

      <MediaPicker
        open={mediaPickerOpen}
        onClose={() => setMediaPickerOpen(false)}
        onSelect={(url) => {
          setImageUrl(url);
          message.success('已选择图片');
        }}
      />
    </PageContainer>
  );
}
