import { useEffect, useState } from 'react';
import { Link, useSearchParams } from 'react-router-dom';
import {
  Alert, Button, Form, Image, Input, InputNumber, Modal, Popconfirm, Select, Space, Table, Tag, message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  ACTIVITY_POSTER_STATUS_LABELS,
  ACTIVITY_POSTER_UPLOAD_HINT,
  DEFAULT_ACTIVITY_POSTER_QR_SLOT,
  type ActivityPosterItem,
  type ActivityPosterQrSlot,
  type ActivityPosterStatus,
} from '@dukang/shared-types';
import { request, requestDownload } 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';
import OssUpload from '../components/OssUpload';
import ActivityPosterQrSlotEditor from '../components/ActivityPosterQrSlotEditor';

type FormValues = {
  title: string;
  copyText?: string;
  imageUrl: string;
  qrXPct: number;
  qrYPct: number;
  qrSizePct: number;
  sortOrder?: number;
  status?: ActivityPosterStatus;
};

type PartnerHint = {
  id: string;
  companyName?: string | null;
  name?: string;
  phone?: string;
};

export default function ActivityPostersPage() {
  const [searchParams] = useSearchParams();
  const partnerId = searchParams.get('partnerId')?.trim() || '';
  const [form] = Form.useForm();
  const [editForm] = Form.useForm<FormValues>();
  const [filters, setFilters] = useState<Record<string, string>>({});
  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<ActivityPosterItem>(
    '/admin/activity-posters',
    () => {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      return qs;
    },
    [filters],
  );
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<ActivityPosterItem | null>(null);
  const [partnerHint, setPartnerHint] = useState<PartnerHint | null>(null);
  const [downloadingId, setDownloadingId] = useState<string | null>(null);

  const imageUrl = Form.useWatch('imageUrl', editForm);
  const qrXPct = Form.useWatch('qrXPct', editForm);
  const qrYPct = Form.useWatch('qrYPct', editForm);
  const qrSizePct = Form.useWatch('qrSizePct', editForm);
  const slot: ActivityPosterQrSlot = {
    qrXPct: qrXPct ?? DEFAULT_ACTIVITY_POSTER_QR_SLOT.qrXPct,
    qrYPct: qrYPct ?? DEFAULT_ACTIVITY_POSTER_QR_SLOT.qrYPct,
    qrSizePct: qrSizePct ?? DEFAULT_ACTIVITY_POSTER_QR_SLOT.qrSizePct,
  };

  useEffect(() => {
    if (!partnerId) {
      setPartnerHint(null);
      return;
    }
    void request<PartnerHint>(`/admin/partners/${partnerId}`)
      .then(setPartnerHint)
      .catch(() => setPartnerHint({ id: partnerId }));
  }, [partnerId]);

  const partnerLabel = partnerHint
    ? (partnerHint.companyName || partnerHint.name || partnerHint.phone || partnerHint.id)
    : partnerId;

  function openCreate() {
    setEditing(null);
    editForm.setFieldsValue({
      title: '',
      copyText: '',
      imageUrl: '',
      ...DEFAULT_ACTIVITY_POSTER_QR_SLOT,
      sortOrder: 0,
      status: 'ACTIVE',
    });
    setModalOpen(true);
  }

  function openEdit(row: ActivityPosterItem) {
    setEditing(row);
    editForm.setFieldsValue({
      title: row.title,
      copyText: row.copyText,
      imageUrl: row.imageUrl,
      qrXPct: row.qrXPct,
      qrYPct: row.qrYPct,
      qrSizePct: row.qrSizePct,
      sortOrder: row.sortOrder,
      status: row.status,
    });
    setModalOpen(true);
  }

  async function save() {
    const v = await editForm.validateFields();
    const body = JSON.stringify(v);
    if (editing) {
      await request(`/admin/activity-posters/${editing.id}`, { method: 'PUT', body });
      message.success('已保存');
    } else {
      await request('/admin/activity-posters', { method: 'POST', body });
      message.success('已创建');
    }
    setModalOpen(false);
    void reload();
  }

  async function downloadForPartner(posterId: string) {
    if (!partnerId) return;
    setDownloadingId(posterId);
    try {
      await requestDownload(
        `/admin/activity-posters/${posterId}/image?partnerId=${encodeURIComponent(partnerId)}`,
        {},
        'activity-poster.png',
      );
      message.success('已开始下载');
    } catch (e) {
      message.error(e instanceof Error ? e.message : '下载失败');
    } finally {
      setDownloadingId(null);
    }
  }

  const baseColumns: ColumnsType<ActivityPosterItem> = [
    {
      title: '标题',
      dataIndex: 'title',
      width: 180,
      render: (v, row) => <AdminPrimaryLink onClick={() => openEdit(row)}>{v}</AdminPrimaryLink>,
    },
    {
      title: '封面',
      dataIndex: 'imageUrl',
      width: 90,
      render: (url: string) => <Image src={url} width={56} height={56} style={{ objectFit: 'cover' }} />,
    },
    {
      title: '文案',
      dataIndex: 'copyText',
      width: 240,
      render: (v: string) => v || '—',
    },
    { title: '排序', dataIndex: 'sortOrder', width: 70 },
    {
      title: '状态',
      dataIndex: 'status',
      width: 80,
      render: (s: ActivityPosterStatus) => (
        <Tag color={s === 'ACTIVE' ? 'green' : 'default'}>{ACTIVITY_POSTER_STATUS_LABELS[s] || s}</Tag>
      ),
    },
    { title: '更新', dataIndex: 'updatedAt', width: 160, render: fmtTime },
    {
      title: '操作',
      width: partnerId ? 280 : 200,
      render: (_, row) => (
        <Space>
          <Button type="link" size="small" onClick={() => openEdit(row)}>编辑</Button>
          {partnerId && row.status === 'ACTIVE' ? (
            <Button
              type="link"
              size="small"
              loading={downloadingId === row.id}
              onClick={() => void downloadForPartner(row.id)}
            >
              为该合伙人下载
            </Button>
          ) : null}
          <Button
            type="link"
            size="small"
            onClick={async () => {
              const next = row.status === 'ACTIVE' ? 'DISABLED' : 'ACTIVE';
              await request(`/admin/activity-posters/${row.id}/status`, {
                method: 'PUT',
                body: JSON.stringify({ status: next }),
              });
              message.success(next === 'ACTIVE' ? '已上架' : '已下架');
              void reload();
            }}
          >
            {row.status === 'ACTIVE' ? '下架' : '上架'}
          </Button>
          <Popconfirm
            title="确认删除该活动图？"
            onConfirm={async () => {
              await request(`/admin/activity-posters/${row.id}`, { method: 'DELETE' });
              message.success('已删除');
              void reload();
            }}
          >
            <Button type="link" size="small" danger>删除</Button>
          </Popconfirm>
        </Space>
      ),
    },
  ];

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

  return (
    <div>
      {settingsModal}
      <AdminListHeader
        title="活动图"
        settings={settingsButton}
        actions={<Button type="primary" onClick={openCreate}>新建活动图</Button>}
      />
      {partnerId ? (
        <Alert
          type="info"
          showIcon
          style={{ marginBottom: 16 }}
          message={
            <>
              正在为合伙人「{partnerLabel}」下载活动图。点行内「为该合伙人下载」，或返回{' '}
              <Link to="/city-partners">城市合伙人</Link>。
            </>
          }
        />
      ) : null}
      <Form form={form} layout="inline" style={{ marginBottom: 16 }} onFinish={(v) => { setFilters(v); setPage(1); }}>
        <Form.Item name="status" label="状态">
          <Select
            allowClear
            style={{ width: 120 }}
            options={Object.entries(ACTIVITY_POSTER_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={editing ? '编辑活动图' : '新建活动图'}
        open={modalOpen}
        onCancel={() => setModalOpen(false)}
        onOk={() => void save()}
        width={720}
        destroyOnClose
      >
        <Form form={editForm} layout="vertical">
          <Form.Item name="title" label="标题" rules={[{ required: true, message: '请填写标题' }]}>
            <Input maxLength={128} />
          </Form.Item>
          <Form.Item name="imageUrl" label="活动图" rules={[{ required: true, message: '请上传活动图' }]}>
            <OssUpload bizType="ACTIVITY_POSTER" uploadHint={ACTIVITY_POSTER_UPLOAD_HINT} />
          </Form.Item>
          <Form.Item name="qrXPct" hidden><InputNumber /></Form.Item>
          <Form.Item name="qrYPct" hidden><InputNumber /></Form.Item>
          <Form.Item name="qrSizePct" hidden><InputNumber /></Form.Item>
          <Form.Item label="二维码栏">
            <ActivityPosterQrSlotEditor
              imageUrl={imageUrl}
              value={slot}
              onChange={(next) => editForm.setFieldsValue(next)}
            />
          </Form.Item>
          <Form.Item name="copyText" label="推广文案">
            <Input.TextArea rows={4} maxLength={4000} placeholder="合伙人可一键复制" />
          </Form.Item>
          <Form.Item name="sortOrder" label="排序" initialValue={0}>
            <InputNumber min={0} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="status" label="状态" initialValue="ACTIVE">
            <Select options={Object.entries(ACTIVITY_POSTER_STATUS_LABELS).map(([value, label]) => ({ value, label }))} />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}
