import { useEffect, useState } from 'react';
import {
  Button,
  Drawer,
  Input,
  Modal,
  Space,
  Table,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type {
  StorePackageAuditDetailDto,
  StorePackageChangeRequestDto,
  StorePackageItemDto,
  StorePackageViewDto,
} from '@dukang/shared-types';
import { STORE_PACKAGE_CHANGE_STATUS_LABELS } from '@dukang/shared-types';
import { request, type Paginated } from '../lib/api';
import { fmtTime } from '../lib/constants';

function packageKey(pkg: StorePackageItemDto | StorePackageViewDto, index: number) {
  const name = String(pkg.name ?? '').trim();
  return name ? `name:${name}` : `idx:${index}`;
}

function diffPackages(live: StorePackageViewDto[], proposed: StorePackageItemDto[]) {
  const liveMap = new Map(live.map((p, i) => [packageKey(p, i), p]));
  const proposedMap = new Map(proposed.map((p, i) => [packageKey(p, i), p]));
  const keys = new Set([...liveMap.keys(), ...proposedMap.keys()]);
  const rows: Array<{
    key: string;
    change: 'added' | 'removed' | 'changed' | 'unchanged';
    live?: StorePackageViewDto;
    proposed?: StorePackageItemDto;
  }> = [];

  for (const key of keys) {
    const l = liveMap.get(key);
    const p = proposedMap.get(key);
    if (l && !p) {
      rows.push({ key, change: 'removed', live: l });
    } else if (!l && p) {
      rows.push({ key, change: 'added', proposed: p });
    } else if (l && p) {
      const changed =
        l.price !== p.price ||
        l.dishes !== p.dishes ||
        (l.usableTime ?? '') !== (p.usableTime ?? '') ||
        (l.otherNotes ?? '') !== (p.otherNotes ?? '');
      rows.push({ key, change: changed ? 'changed' : 'unchanged', live: l, proposed: p });
    }
  }
  return rows;
}

const CHANGE_LABELS = {
  added: { text: '新增', color: 'green' },
  removed: { text: '删除', color: 'red' },
  changed: { text: '变更', color: 'orange' },
  unchanged: { text: '未变', color: 'default' },
} as const;

export default function StorePackageAuditsPage() {
  const [loading, setLoading] = useState(false);
  const [items, setItems] = useState<StorePackageChangeRequestDto[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [status, setStatus] = useState<string>('PENDING');
  const [rejectOpen, setRejectOpen] = useState(false);
  const [rejectReason, setRejectReason] = useState('');
  const [activeId, setActiveId] = useState<string | null>(null);
  const [detailOpen, setDetailOpen] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  const [detail, setDetail] = useState<StorePackageAuditDetailDto | null>(null);

  async function reload(nextPage = page, nextStatus = status) {
    setLoading(true);
    try {
      const qs = new URLSearchParams({
        page: String(nextPage),
        pageSize: '20',
      });
      if (nextStatus) qs.set('status', nextStatus);
      const data = await request<Paginated<StorePackageChangeRequestDto>>(
        `/admin/store-package-audits?${qs}`,
      );
      setItems(data.items);
      setTotal(data.total);
      setPage(data.page);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载失败');
    } finally {
      setLoading(false);
    }
  }

  useEffect(() => {
    void reload(1, status);
  }, [status]);

  async function openDetail(id: string) {
    setDetailOpen(true);
    setDetailLoading(true);
    setDetail(null);
    try {
      const data = await request<StorePackageAuditDetailDto>(`/admin/store-package-audits/${id}`);
      setDetail(data);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载详情失败');
      setDetailOpen(false);
    } finally {
      setDetailLoading(false);
    }
  }

  async function audit(id: string, action: 'APPROVE' | 'REJECT', reason?: string) {
    try {
      await request(`/admin/store-package-audits/${id}/audit`, {
        method: 'PUT',
        body: JSON.stringify(
          action === 'REJECT' ? { action, rejectReason: reason } : { action },
        ),
      });
      message.success(action === 'APPROVE' ? '已通过' : '已驳回');
      setDetailOpen(false);
      void reload(page, status);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '操作失败');
    }
  }

  const diffRows = detail ? diffPackages(detail.livePackages ?? [], detail.packages ?? []) : [];

  const diffColumns: ColumnsType<(typeof diffRows)[number]> = [
    {
      title: '变更',
      dataIndex: 'change',
      width: 72,
      render: (v: keyof typeof CHANGE_LABELS) => {
        const meta = CHANGE_LABELS[v];
        return <Tag color={meta.color}>{meta.text}</Tag>;
      },
    },
    {
      title: '当前线上',
      render: (_, row) =>
        row.live ? (
          <div>
            <div><strong>{row.live.name}</strong> · ¥{row.live.price}</div>
            <Typography.Text type="secondary">{row.live.dishes}</Typography.Text>
            {row.live.usableTime ? (
              <div><Typography.Text type="secondary">可用：{row.live.usableTime}</Typography.Text></div>
            ) : null}
            {row.live.otherNotes ? (
              <div><Typography.Text type="secondary">备注：{row.live.otherNotes}</Typography.Text></div>
            ) : null}
          </div>
        ) : (
          '—'
        ),
    },
    {
      title: '申请变更',
      render: (_, row) =>
        row.proposed ? (
          <div>
            <div><strong>{row.proposed.name}</strong> · ¥{row.proposed.price}</div>
            <Typography.Text type="secondary">{row.proposed.dishes}</Typography.Text>
            {row.proposed.usableTime ? (
              <div><Typography.Text type="secondary">可用：{row.proposed.usableTime}</Typography.Text></div>
            ) : null}
            {row.proposed.otherNotes ? (
              <div><Typography.Text type="secondary">备注：{row.proposed.otherNotes}</Typography.Text></div>
            ) : null}
          </div>
        ) : (
          '—'
        ),
    },
  ];

  const columns: ColumnsType<StorePackageChangeRequestDto> = [
    { title: '门店', dataIndex: 'storeName', render: (_, row) => row.storeName || row.storeId },
    {
      title: '状态',
      dataIndex: 'status',
      render: (v: StorePackageChangeRequestDto['status']) => (
        <Tag>{STORE_PACKAGE_CHANGE_STATUS_LABELS[v] ?? v}</Tag>
      ),
    },
    {
      title: '套餐数',
      render: (_, row) => row.packages?.length ?? 0,
    },
    {
      title: '提交方',
      render: (_, row) => (row.submitterType === 'PARTNER' ? '合伙人' : '门店'),
    },
    { title: '提交时间', dataIndex: 'createdAt', render: (v) => fmtTime(String(v)) },
    {
      title: '操作',
      render: (_, row) => (
        <Space>
          <Button type="link" onClick={() => void openDetail(row.id)}>
            查看变更
          </Button>
          {row.status === 'PENDING' ? (
            <>
              <Button type="link" onClick={() => void audit(row.id, 'APPROVE')}>
                通过
              </Button>
              <Button
                type="link"
                danger
                onClick={() => {
                  setActiveId(row.id);
                  setRejectReason('');
                  setRejectOpen(true);
                }}
              >
                驳回
              </Button>
            </>
          ) : (
            row.rejectReason || null
          )}
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Typography.Title level={4}>套餐变更审核</Typography.Title>
      <Space style={{ marginBottom: 16 }}>
        {(['PENDING', 'APPROVED', 'REJECTED', ''] as const).map((s) => (
          <Button key={s || 'all'} type={status === s ? 'primary' : 'default'} onClick={() => setStatus(s)}>
            {s ? STORE_PACKAGE_CHANGE_STATUS_LABELS[s as keyof typeof STORE_PACKAGE_CHANGE_STATUS_LABELS] : '全部'}
          </Button>
        ))}
      </Space>
      <Table
        rowKey="id"
        loading={loading}
        columns={columns}
        dataSource={items}
        pagination={{
          current: page,
          total,
          pageSize: 20,
          onChange: (p) => void reload(p, status),
        }}
      />

      <Drawer
        title={detail ? `${detail.storeName || detail.storeId} · 套餐变更` : '套餐变更详情'}
        width={720}
        open={detailOpen}
        onClose={() => setDetailOpen(false)}
        extra={
          detail?.status === 'PENDING' ? (
            <Space>
              <Button onClick={() => void audit(detail.id, 'APPROVE')}>通过</Button>
              <Button
                danger
                onClick={() => {
                  setActiveId(detail.id);
                  setRejectReason('');
                  setRejectOpen(true);
                }}
              >
                驳回
              </Button>
            </Space>
          ) : null
        }
      >
        {detailLoading ? (
          <Typography.Text type="secondary">加载中…</Typography.Text>
        ) : detail ? (
          <>
            <Space style={{ marginBottom: 16 }}>
              <Tag>{STORE_PACKAGE_CHANGE_STATUS_LABELS[detail.status]}</Tag>
              <Typography.Text type="secondary">
                提交方：{detail.submitterType === 'PARTNER' ? '合伙人' : '门店'} · {fmtTime(detail.createdAt)}
              </Typography.Text>
            </Space>
            {detail.rejectReason ? (
              <Typography.Paragraph type="danger">驳回原因：{detail.rejectReason}</Typography.Paragraph>
            ) : null}
            <Typography.Paragraph type="secondary">
              线上 {detail.livePackages?.length ?? 0} 条 → 申请 {detail.packages?.length ?? 0} 条
            </Typography.Paragraph>
            <Table
              size="small"
              rowKey="key"
              columns={diffColumns}
              dataSource={diffRows}
              pagination={false}
            />
          </>
        ) : null}
      </Drawer>

      <Modal
        title="驳回套餐变更"
        open={rejectOpen}
        onCancel={() => setRejectOpen(false)}
        onOk={() => {
          if (!activeId) return;
          if (!rejectReason.trim()) {
            message.warning('请填写驳回原因');
            return;
          }
          void audit(activeId, 'REJECT', rejectReason.trim());
          setRejectOpen(false);
        }}
      >
        <Input.TextArea
          rows={3}
          value={rejectReason}
          placeholder="驳回原因"
          onChange={(e) => setRejectReason(e.target.value)}
        />
      </Modal>
    </div>
  );
}
