import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Button, Form, Input, Modal, Select, Space, Table, Tag, Typography, message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  PROMO_CODE_SCENE_LABELS,
  PROMO_CODE_STATUS_LABELS,
  promoConversion,
  type PromoCodeItem,
  type PromoCodeScene,
} from '@dukang/shared-types';
import { request } from '../lib/api';
import { fmtTime } from '../lib/constants';
import { useAdminList } from '../lib/useAdminList';
import { useAdminListColumns } from '../lib/useAdminListColumns';
import { AdminListHeader } from '../components/AdminListHeader';
import { AdminPrimaryLink } from '../components/AdminPrimaryLink';


type Row = PromoCodeItem;

type SceneOption = { value: PromoCodeScene; label: string };

async function downloadQrcode(url: string, filename: string) {
  try {
    const res = await fetch(url);
    const blob = await res.blob();
    const objectUrl = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = objectUrl;
    a.download = filename;
    a.click();
    URL.revokeObjectURL(objectUrl);
  } catch {
    window.open(url, '_blank');
  }
}

export default function PromoCodesPage() {
  const navigate = useNavigate();
  const [filterForm] = Form.useForm();
  const [createForm] = Form.useForm();
  const [filters, setFilters] = useState<Record<string, string>>({});
  const [scenes, setScenes] = useState<SceneOption[]>(
    Object.entries(PROMO_CODE_SCENE_LABELS).map(([value, label]) => ({
      value: value as PromoCodeScene,
      label,
    })),
  );
  const [createOpen, setCreateOpen] = useState(false);
  const [creating, setCreating] = useState(false);

  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<Row>(
    '/admin/promo-codes',
    () => {
      const qs = new URLSearchParams();
      if (filters.name) qs.set('name', filters.name);
      if (filters.code) qs.set('code', filters.code);
      if (filters.status) qs.set('status', filters.status);
      if (filters.scene) qs.set('scene', filters.scene);
      return qs;
    },
    [filters],
  );

  async function loadScenes() {
    try {
      const list = await request<SceneOption[]>('/admin/promo-codes/scenes');
      if (list.length) setScenes(list);
    } catch {
      /* 使用本地默认场景 */
    }
  }

  useEffect(() => {
    void loadScenes();
  }, []);

  const baseColumns: ColumnsType<Row> = [
    {
      title: '名称',
      dataIndex: 'name',
      width: 160,
      render: (v, row) => (
        <AdminPrimaryLink onClick={() => navigate(`/promo-codes/${row.id}`)}>{v}</AdminPrimaryLink>
      ),
    },
    { title: '码值', dataIndex: 'code', width: 110 },
    {
      title: '场景',
      dataIndex: 'scene',
      width: 110,
      render: (s: PromoCodeScene) => PROMO_CODE_SCENE_LABELS[s] || s,
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 90,
      render: (s) => (
        <Tag color={s === 'ACTIVE' ? 'green' : 'default'}>
          {PROMO_CODE_STATUS_LABELS[s as keyof typeof PROMO_CODE_STATUS_LABELS] || s}
        </Tag>
      ),
    },
    { title: '扫码', dataIndex: 'scanCount', width: 70 },
    { title: '订单', dataIndex: 'orderCount', width: 70 },
    {
      title: '转化率',
      width: 90,
      render: (_, row) => promoConversion(row.scanCount, row.orderCount),
    },
    {
      title: '渠道负责人',
      width: 120,
      render: (_, row) => row.ownerUser?.userNo || row.ownerUser?.phone || '—',
    },
    { title: '创建', dataIndex: 'createdAt', width: 160, render: fmtTime },
    {
      title: '操作',
      width: 220,
      fixed: 'right',
      render: (_, row) => (
        <Space size="small" wrap>
          <Button type="link" size="small" onClick={() => navigate(`/promo-codes/${row.id}`)}>
            详情
          </Button>
          <Button
            type="link"
            size="small"
            disabled={!row.qrcodeUrl}
            onClick={() => {
              if (!row.qrcodeUrl) return;
              void downloadQrcode(row.qrcodeUrl, `${row.code}-wxacode.png`);
            }}
          >
            下载小程序码
          </Button>
          <Button type="link" size="small" onClick={() => navigate(`/promo-codes/${row.id}/users`)}>
            关联用户
          </Button>
        </Space>
      ),
    },
  ];

  async function handleCreate(values: Record<string, string>) {
    setCreating(true);
    try {
      const created = await request<PromoCodeItem>('/admin/promo-codes', {
        method: 'POST',
        body: JSON.stringify({
          name: values.name,
          code: values.code?.trim() || undefined,
          scene: values.scene,
          ownerUserId: values.ownerUserId?.trim() || undefined,
          remark: values.remark?.trim() || undefined,
          page: values.page?.trim() || undefined,
        }),
      });
      message.success('推广码已创建');
      setCreateOpen(false);
      createForm.resetFields();
      void reload();
      navigate(`/promo-codes/${created.id}`);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '创建失败');
    } finally {
      setCreating(false);
    }
  }

  const { columns, settingsButton, settingsModal } = useAdminListColumns('promo-codes', baseColumns, { page, pageSize });

  return (
    <div>
      {settingsModal}
      <AdminListHeader
        title="推广码管理"
        settings={settingsButton}
        actions={<Button type="primary" onClick={() => setCreateOpen(true)}>创建推广码</Button>}
      />

      <Form
        form={filterForm}
        layout="inline"
        style={{ marginBottom: 16 }}
        onFinish={(v) => { setFilters(v); setPage(1); }}
      >
        <Form.Item name="name" label="名称"><Input allowClear /></Form.Item>
        <Form.Item name="code" label="码值"><Input allowClear /></Form.Item>
        <Form.Item name="scene" label="场景">
          <Select allowClear style={{ width: 130 }} options={scenes} />
        </Form.Item>
        <Form.Item name="status" label="状态">
          <Select
            allowClear
            style={{ width: 100 }}
            options={Object.entries(PROMO_CODE_STATUS_LABELS).map(([value, label]) => ({ value, label }))}
          />
        </Form.Item>
        <Form.Item><Button type="primary" htmlType="submit">查询</Button></Form.Item>
      </Form>

      <Table
        rowKey="id"
        className="admin-table-nowrap"
        loading={loading}
        columns={columns}
        dataSource={data?.items ?? []}
        scroll={{ x: 'max-content' }}
        pagination={{
          current: page,
          pageSize,
          total: data?.total ?? 0,
          showSizeChanger: true,
          onChange: (p, ps) => { setPage(p); setPageSize(ps); },
        }}
      />

      <Modal
        title="创建推广码"
        open={createOpen}
        onCancel={() => setCreateOpen(false)}
        footer={null}
        destroyOnClose
      >
        <Form form={createForm} layout="vertical" onFinish={handleCreate} initialValues={{ scene: 'ONLINE_LINK' }}>
          <Form.Item name="name" label="推广码名称" rules={[{ required: true, message: '请填写名称' }]}>
            <Input placeholder="如：郑州品鉴会、门店地推" />
          </Form.Item>
          <Form.Item name="scene" label="场景" rules={[{ required: true }]}>
            <Select options={scenes} />
          </Form.Item>
          <Form.Item name="code" label="自定义码值（选填）">
            <Input placeholder="留空自动生成，如 DKDEMO1" />
          </Form.Item>
          <Form.Item
            name="page"
            label="小程序落地页（选填）"
            extra="如 pages/home/index；留空则使用服务端环境变量 WX_MINI_PROMO_PAGE"
          >
            <Input placeholder="pages/home/index" />
          </Form.Item>
          <Form.Item name="ownerUserId" label="关联用户 ID（选填）">
            <Input placeholder="渠道负责人，填写用户数据库 ID" />
          </Form.Item>
          <Form.Item name="remark" label="备注">
            <Input.TextArea rows={2} placeholder="渠道说明、活动备注等" />
          </Form.Item>
          <Button type="primary" htmlType="submit" loading={creating} block>
            创建并生成小程序码
          </Button>
        </Form>
      </Modal>
    </div>
  );
}
