import { useEffect, useState } from 'react';
import {
  Button,
  Card,
  DatePicker,
  Form,
  Input,
  Modal,
  Select,
  Space,
  Statistic,
  Table,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import dayjs, { type Dayjs } from 'dayjs';
import { request, type Paginated } from '../lib/api';
import { ADMIN_OPTIONS_PAGE_SIZE, fmtTime } from '../lib/constants';
import { downloadExcelCsv } from '../lib/exportExcel';
import { useAdminList } from '../lib/useAdminList';

type Row = {
  id: string;
  billNo: string;
  orderCommission: number;
  redeemCommission: number;
  totalAmount: number;
  status: string;
  periodStart: string;
  periodEnd: string;
  rejectReason?: string | null;
  partner?: { companyName?: string; phone?: string };
  partnerAccount?: { companyName?: string; phone?: string };
};

type PartnerOption = { id: string; companyName: string; phone?: string };

const STATUS_LABELS: Record<string, string> = {
  PENDING_REVIEW: '待审核',
  AWAITING_CONFIRM: '待合伙人确认',
  UNPAID: '未打款',
  PAID: '已打款',
  REJECTED: '已驳回',
};

const STATUS_COLORS: Record<string, string> = {
  PENDING_REVIEW: 'gold',
  AWAITING_CONFIRM: 'blue',
  UNPAID: 'red',
  PAID: 'green',
  REJECTED: 'red',
};

export default function PartnerBillsPage() {
  const [form] = Form.useForm();
  const [filters, setFilters] = useState<Record<string, string>>({});
  const [partners, setPartners] = useState<PartnerOption[]>([]);
  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<Row>(
    '/admin/partner-bills',
    () => {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      if (filters.partnerId) qs.set('partnerId', filters.partnerId);
      if (filters.year) qs.set('year', filters.year);
      if (filters.month) qs.set('month', filters.month);
      return qs;
    },
    [filters],
  );
  const [genOpen, setGenOpen] = useState(false);
  const [genForm] = Form.useForm();
  const [exporting, setExporting] = useState(false);
  const [rejectOpen, setRejectOpen] = useState(false);
  const [rejectTarget, setRejectTarget] = useState<Row | null>(null);
  const [rejectForm] = Form.useForm();
  const [rejecting, setRejecting] = useState(false);
  const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);

  useEffect(() => {
    void request<Paginated<PartnerOption>>(`/admin/partners?pageSize=${ADMIN_OPTIONS_PAGE_SIZE}`)
      .then((res) => setPartners(res.items))
      .catch(() => {});
  }, []);

  async function generateBill(values: { partnerId?: string; month: Dayjs }) {
    const year = values.month.year();
    const month = values.month.month() + 1;
    if (!values.partnerId) {
      const result = await request<{ success: number; failed: number; total: number }>(
        '/admin/partner-bills/generate-all',
        { method: 'POST', body: JSON.stringify({ year, month }) },
      );
      message.success(`已生成 ${result.success}/${result.total} 份账单${result.failed ? `，失败 ${result.failed}` : ''}`);
    } else {
      await request('/admin/partner-bills/generate', {
        method: 'POST',
        body: JSON.stringify({ partnerId: values.partnerId, year, month }),
      });
      message.success('账单已生成（待审核）');
    }
    setGenOpen(false);
    reload();
  }

  function sendBills(ids: string[]) {
    Modal.confirm({
      title: '发送给合伙人？',
      content: `将发送 ${ids.length} 笔账单到合伙人端，状态变为「待合伙人确认」。`,
      okText: '确认发送',
      cancelText: '取消',
      onOk: async () => {
        if (ids.length === 1) {
          await request(`/admin/partner-bills/${ids[0]}/send`, { method: 'POST' });
        } else {
          await request('/admin/partner-bills/batch-send', {
            method: 'POST',
            body: JSON.stringify({ ids }),
          });
        }
        message.success('已发送');
        setSelectedKeys([]);
        reload();
      },
    });
  }

  function markPaid(ids: string[], amountHint?: number) {
    Modal.confirm({
      title: '确认打款？',
      content: `将标记 ${ids.length} 笔账单为已打款${amountHint != null ? `，合计约 ¥${amountHint.toFixed(2)}` : ''}。`,
      okText: '确认打款',
      cancelText: '取消',
      onOk: async () => {
        if (ids.length === 1) {
          await request(`/admin/partner-bills/${ids[0]}/mark-paid`, {
            method: 'POST',
            body: JSON.stringify({ paymentRef: `PAY-${Date.now()}` }),
          });
        } else {
          await request('/admin/partner-bills/batch-mark-paid', {
            method: 'POST',
            body: JSON.stringify({ ids }),
          });
        }
        message.success('已标记打款');
        setSelectedKeys([]);
        reload();
      },
    });
  }

  function openReject(row: Row) {
    Modal.confirm({
      title: '驳回该账单？',
      content: '驳回后合伙人需重新等待总部发送。请在下一步填写理由。',
      okText: '继续填写理由',
      cancelText: '取消',
      onOk: () => {
        setRejectTarget(row);
        rejectForm.resetFields();
        setRejectOpen(true);
      },
    });
  }

  async function submitReject(values: { reason: string }) {
    if (!rejectTarget) return;
    setRejecting(true);
    try {
      await request(`/admin/partner-bills/${rejectTarget.id}/reject`, {
        method: 'POST',
        body: JSON.stringify({ reason: values.reason.trim() }),
      });
      message.success('已驳回');
      setRejectOpen(false);
      setRejectTarget(null);
      reload();
    } finally {
      setRejecting(false);
    }
  }

  async function exportExcel() {
    setExporting(true);
    try {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      if (filters.partnerId) qs.set('partnerId', filters.partnerId);
      if (filters.year) qs.set('year', filters.year);
      if (filters.month) qs.set('month', filters.month);
      const result = await request<{ csv: string; count: number }>(`/admin/partner-bills/export?${qs}`);
      const suffix = filters.year && filters.month ? `${filters.year}-${filters.month}` : 'all';
      downloadExcelCsv(result.csv, `合伙人账单_${suffix}.csv`);
      message.success(`已导出 ${result.count} 条`);
    } finally {
      setExporting(false);
    }
  }

  const summary = data?.summary;
  const partnerName = (r: Row) => r.partner?.companyName || r.partnerAccount?.companyName || '—';
  const selectedRows = (data?.items ?? []).filter((r) => selectedKeys.includes(r.id));
  const canSend = selectedRows.filter((r) => r.status === 'PENDING_REVIEW' || r.status === 'REJECTED');
  const canPay = selectedRows.filter((r) => r.status === 'UNPAID');
  const payAmount = canPay.reduce((s, r) => s + Number(r.totalAmount), 0);

  const columns: ColumnsType<Row> = [
    { title: '账单号', dataIndex: 'billNo', width: 180, ellipsis: true },
    {
      title: '合伙人',
      width: 160,
      ellipsis: true,
      render: (_, r) => partnerName(r),
    },
    {
      title: '账期',
      width: 200,
      render: (_, r) =>
        `${fmtTime(r.periodStart).slice(0, 10)} ~ ${fmtTime(r.periodEnd).slice(0, 10)}`,
    },
    {
      title: '酒单佣金',
      dataIndex: 'orderCommission',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '核销佣金',
      dataIndex: 'redeemCommission',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '合计应付',
      dataIndex: 'totalAmount',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 130,
      render: (s, row) => (
        <Space direction="vertical" size={0}>
          <Tag color={STATUS_COLORS[s] || 'default'}>{STATUS_LABELS[s] || s}</Tag>
          {s === 'REJECTED' && row.rejectReason ? (
            <Typography.Text type="secondary" style={{ fontSize: 12 }}>
              {row.rejectReason}
            </Typography.Text>
          ) : null}
        </Space>
      ),
    },
    {
      title: '操作',
      width: 220,
      fixed: 'right',
      render: (_, row) => (
        <Space size={0} wrap>
          {(row.status === 'PENDING_REVIEW' || row.status === 'REJECTED') && (
            <Button type="link" size="small" onClick={() => sendBills([row.id])}>
              发送
            </Button>
          )}
          {row.status === 'UNPAID' && (
            <>
              <Button type="link" size="small" onClick={() => markPaid([row.id], Number(row.totalAmount))}>
                确认打款
              </Button>
              <Button type="link" size="small" danger onClick={() => openReject(row)}>
                驳回
              </Button>
            </>
          )}
          {row.status === 'AWAITING_CONFIRM' && (
            <Button type="link" size="small" danger onClick={() => openReject(row)}>
              驳回
            </Button>
          )}
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Space direction="vertical" size={0} style={{ marginBottom: 16 }}>
        <Typography.Title level={4} style={{ margin: 0 }}>
          合伙人账单
        </Typography.Title>
        <Typography.Text type="secondary">
          每月 1 日 8:00 自动生成上月账单（待审核）→ 发送合伙人确认 → 未打款 → 已打款
        </Typography.Text>
      </Space>

      {summary && (
        <Card size="small" style={{ marginBottom: 16 }}>
          <Space size="large" wrap>
            <Statistic title="账单数" value={summary.count} />
            <Statistic title="酒单佣金合计" value={summary.orderCommission ?? 0} prefix="¥" precision={2} />
            <Statistic title="核销佣金合计" value={summary.redeemCommission ?? 0} prefix="¥" precision={2} />
            <Statistic title="应付合计" value={summary.totalAmount} prefix="¥" precision={2} />
          </Space>
        </Card>
      )}

      <Form
        form={form}
        layout="inline"
        style={{ marginBottom: 16 }}
        onFinish={(v: { partnerId?: string; status?: string; month?: Dayjs }) => {
          setFilters({
            partnerId: v.partnerId || '',
            status: v.status || '',
            year: v.month ? String(v.month.year()) : '',
            month: v.month ? String(v.month.month() + 1) : '',
          });
          setPage(1);
        }}
      >
        <Form.Item name="partnerId" label="合伙人">
          <Select
            allowClear
            showSearch
            placeholder="全部合伙人"
            style={{ width: 220 }}
            optionFilterProp="label"
            options={partners.map((p) => ({
              value: p.id,
              label: p.companyName || p.phone || p.id,
            }))}
          />
        </Form.Item>
        <Form.Item name="month" label="账期月">
          <DatePicker picker="month" />
        </Form.Item>
        <Form.Item name="status" label="状态">
          <Select
            allowClear
            style={{ width: 150 }}
            options={Object.entries(STATUS_LABELS).map(([value, label]) => ({ value, label }))}
          />
        </Form.Item>
        <Form.Item>
          <Button type="primary" htmlType="submit">
            查询
          </Button>
        </Form.Item>
        <Form.Item>
          <Button
            onClick={() => {
              form.resetFields();
              setFilters({});
              setPage(1);
            }}
          >
            重置
          </Button>
        </Form.Item>
        <Form.Item>
          <Button type="primary" onClick={() => setGenOpen(true)}>
            生成账单
          </Button>
        </Form.Item>
        <Form.Item>
          <Button loading={exporting} onClick={() => void exportExcel()}>
            导出 Excel
          </Button>
        </Form.Item>
        <Form.Item>
          <Button disabled={!canSend.length} onClick={() => sendBills(canSend.map((r) => r.id))}>
            批量发送 ({canSend.length})
          </Button>
        </Form.Item>
        <Form.Item>
          <Button
            type="primary"
            disabled={!canPay.length}
            onClick={() => markPaid(canPay.map((r) => r.id), payAmount)}
          >
            批量打款 ({canPay.length})
          </Button>
        </Form.Item>
      </Form>

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

      <Modal title="生成合伙人账单" open={genOpen} onCancel={() => setGenOpen(false)} footer={null}>
        <Form
          form={genForm}
          layout="vertical"
          initialValues={{ month: dayjs().subtract(1, 'month') }}
          onFinish={generateBill}
        >
          <Form.Item name="month" label="账单月份" rules={[{ required: true }]}>
            <DatePicker picker="month" style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="partnerId" label="指定合伙人（留空则全部主合伙人）">
            <Select
              allowClear
              showSearch
              optionFilterProp="label"
              placeholder="全部主合伙人"
              options={partners.map((p) => ({
                value: p.id,
                label: p.companyName || p.phone || p.id,
              }))}
            />
          </Form.Item>
          <Button type="primary" htmlType="submit" block>
            生成（待审核）
          </Button>
        </Form>
      </Modal>

      <Modal
        title="驳回打款申请"
        open={rejectOpen}
        onCancel={() => {
          setRejectOpen(false);
          setRejectTarget(null);
        }}
        footer={null}
        destroyOnClose
      >
        <Typography.Paragraph type="secondary" style={{ marginBottom: 12 }}>
          账单 {rejectTarget?.billNo} · {rejectTarget ? partnerName(rejectTarget) : ''}
        </Typography.Paragraph>
        <Form form={rejectForm} layout="vertical" onFinish={(v) => void submitReject(v)}>
          <Form.Item
            name="reason"
            label="驳回理由"
            rules={[
              { required: true, message: '请填写驳回理由' },
              { max: 500, message: '不超过 500 字' },
            ]}
          >
            <Input.TextArea rows={4} placeholder="请说明驳回原因" maxLength={500} showCount />
          </Form.Item>
          <Button type="primary" danger htmlType="submit" block loading={rejecting}>
            确认驳回
          </Button>
        </Form>
      </Modal>
    </div>
  );
}
