import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Button,
  Card,
  DatePicker,
  Descriptions,
  Drawer,
  Form,
  Input,
  InputNumber,
  Modal,
  Select,
  Space,
  Statistic,
  Table,
  Tabs,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { Dayjs } from 'dayjs';
import dayjs from 'dayjs';
import {
  LOGISTICS_SETTLEMENT_METHOD_LABELS,
  type LogisticsSettlementMethod,
} from '@dukang/shared-types';
import { fmtTime } from '../lib/constants';
import { downloadExcelCsv } from '../lib/exportExcel';
import { appendExportColumns } from '../lib/export-columns';
import { request } from '../lib/api';
import { useAdminList } from '../lib/useAdminList';
import { useAdminListColumns } from '../lib/useAdminListColumns';
import { AdminListHeader } from '../components/AdminListHeader';
import { AdminPrimaryLink } from '../components/AdminPrimaryLink';

type BillRow = {
  id: string;
  billNo: string;
  fulfillmentProviderId: string;
  providerCode?: string;
  providerName?: string;
  periodStart: string;
  periodEnd: string;
  orderCount: number;
  bottleCount: number;
  logisticsAmount: number;
  settlementMethod: string;
  status: string;
  paidAt?: string | null;
  paymentRef?: string | null;
  fulfillmentProvider?: {
    bankAccountName?: string | null;
    bankName?: string | null;
    bankBranch?: string | null;
    bankAccountNo?: string | null;
  };
};

type BillItem = {
  id: string;
  orderNo: string;
  quantity: number;
  logisticsAmount: number;
  shippedAt: string;
};

type ProviderSummary = {
  providerId: string;
  providerCode: string;
  providerName: string;
  settlementMethod: string;
  prepaidBalance: number;
  bankAccountName?: string | null;
  bankName?: string | null;
  bankAccountNo?: string | null;
  orderCount: number;
  bottleCount: number;
  logisticsAmount: number;
  billId?: string | null;
  billStatus?: string | null;
  pricingRules?: {
    baseBottles: number;
    baseFee: number;
    extraBottleFee: number;
    boxBottles?: number;
    boxFee?: number;
  } | null;
};

const STATUS_LABELS: Record<string, string> = {
  UNPAID: '未结算',
  PAID: '已结算',
};

const STATUS_COLORS: Record<string, string> = {
  UNPAID: 'red',
  PAID: 'green',
};

export default function LogisticsBillsPage() {
  const navigate = useNavigate();
  const [form] = Form.useForm();
  const [summaryForm] = Form.useForm();
  const [filters, setFilters] = useState<Record<string, string>>({});
  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<BillRow>(
    '/admin/logistics-bills',
    () => {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      if (filters.providerId) qs.set('providerId', filters.providerId);
      if (filters.year) qs.set('year', filters.year);
      if (filters.month) qs.set('month', filters.month);
      return qs;
    },
    [filters],
  );
  const [exporting, setExporting] = useState(false);
  const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
  const [detail, setDetail] = useState<(BillRow & { items?: BillItem[] }) | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [providers, setProviders] = useState<Array<{ id: string; code: string; name: string }>>([]);
  const [summaryRows, setSummaryRows] = useState<ProviderSummary[]>([]);
  const [summaryLoading, setSummaryLoading] = useState(false);
  const [summaryPeriod, setSummaryPeriod] = useState(() => dayjs().subtract(1, 'month'));
  const [genOpen, setGenOpen] = useState(false);
  const [genForm] = Form.useForm();
  const [rechargeOpen, setRechargeOpen] = useState(false);
  const [rechargeTarget, setRechargeTarget] = useState<ProviderSummary | null>(null);
  const [rechargeForm] = Form.useForm();

  useEffect(() => {
    request<Array<{ id: string; code: string; name: string }>>('/admin/fulfillment-providers')
      .then((rows) => setProviders(rows.map((r) => ({ id: r.id, code: r.code, name: r.name }))))
      .catch(() => {});
  }, []);

  async function loadSummary(period: Dayjs) {
    setSummaryLoading(true);
    try {
      const res = await request<{ items: ProviderSummary[] }>(
        `/admin/logistics-bills/provider-summary?year=${period.year()}&month=${period.month() + 1}`,
      );
      setSummaryRows(res.items ?? []);
    } finally {
      setSummaryLoading(false);
    }
  }

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

  function confirmPay(ids: string[], amountHint?: number) {
    let paymentRef = '';
    Modal.confirm({
      title: '确认结算？',
      content: (
        <div>
          <div>
            将确认 {ids.length} 笔物流对账单
            {amountHint != null ? `，合计约 ¥${amountHint.toFixed(2)}` : ''}。充值模式将扣减余额，挂账模式标记已打款。
          </div>
          <Input
            placeholder="打款凭证号（可选）"
            style={{ marginTop: 8 }}
            onChange={(e) => {
              paymentRef = e.target.value;
            }}
          />
        </div>
      ),
      okText: '确认结算',
      cancelText: '取消',
      onOk: async () => {
        const body = JSON.stringify({ paymentRef: paymentRef.trim() || undefined });
        if (ids.length === 1) {
          await request(`/admin/logistics-bills/${ids[0]}/confirm`, { method: 'POST', body });
        } else {
          await request('/admin/logistics-bills/batch-confirm', {
            method: 'POST',
            body: JSON.stringify({ ids }),
          });
        }
        message.success('已确认结算');
        setSelectedKeys([]);
        reload();
        void loadSummary(summaryPeriod);
      },
    });
  }

  async function openDetail(id: string) {
    const d = await request<BillRow & { items?: BillItem[] }>(`/admin/logistics-bills/${id}`);
    setDetail(d);
    setDrawerOpen(true);
  }

  async function exportExcel() {
    setExporting(true);
    try {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      if (filters.providerId) qs.set('providerId', filters.providerId);
      if (filters.year) qs.set('year', filters.year);
      if (filters.month) qs.set('month', filters.month);
      appendExportColumns(qs, exportColumnKeys);
      const result = await request<{ csv: string; count: number }>(
        `/admin/logistics-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);
    }
  }

  async function generateBills() {
    const v = await genForm.validateFields();
    const month = v.month as Dayjs;
    await request('/admin/logistics-bills/generate', {
      method: 'POST',
      body: JSON.stringify({
        year: month.year(),
        month: month.month() + 1,
        providerId: v.providerId || undefined,
      }),
    });
    message.success('已生成物流对账单');
    setGenOpen(false);
    reload();
    void loadSummary(summaryPeriod);
  }

  async function submitRecharge() {
    if (!rechargeTarget) return;
    const v = await rechargeForm.validateFields();
    await request(`/admin/fulfillment-providers/${rechargeTarget.providerId}/recharge`, {
      method: 'POST',
      body: JSON.stringify({ amount: v.amount, remark: v.remark }),
    });
    message.success('充值成功');
    setRechargeOpen(false);
    void loadSummary(summaryPeriod);
  }

  const summary = data?.summary;
  const providerBank = (r: BillRow) => r.fulfillmentProvider;
  const selectedRows = (data?.items ?? []).filter((r) => selectedKeys.includes(r.id));
  const selectedAmount = selectedRows.reduce((s, r) => s + Number(r.logisticsAmount), 0);

  const billColumns: ColumnsType<BillRow> = [
    {
      title: '账单号',
      key: '账单号',
      dataIndex: 'billNo',
      width: 170,
      render: (v, row) => (
        <AdminPrimaryLink onClick={() => void openDetail(row.id)}>{v}</AdminPrimaryLink>
      ),
    },
    {
      title: '承运商',
      key: '承运商',
      width: 140,
      render: (_, r) => `${r.providerName || ''} (${r.providerCode || ''})`,
    },
    {
      title: '账期',
      key: '账期',
      width: 200,
      render: (_, r) =>
        `${String(r.periodStart || '').slice(0, 10)} ~ ${String(r.periodEnd || '').slice(0, 10)}`,
    },
    {
      title: '结算方式',
      key: '结算方式',
      dataIndex: 'settlementMethod',
      width: 100,
      render: (v) =>
        LOGISTICS_SETTLEMENT_METHOD_LABELS[v as LogisticsSettlementMethod] || v,
    },
    { title: '订单数', key: '订单数', dataIndex: 'orderCount', width: 80 },
    { title: '瓶数', key: '瓶数', dataIndex: 'bottleCount', width: 80 },
    {
      title: '物流费',
      key: '物流费',
      dataIndex: 'logisticsAmount',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '收款户名',
      key: '收款户名',
      width: 100,
      render: (_, r) => providerBank(r)?.bankAccountName || '—',
    },
    {
      title: '收款账号',
      key: '收款账号',
      width: 140,
      render: (_, r) => providerBank(r)?.bankAccountNo || '—',
    },
    {
      title: '状态',
      key: '状态',
      dataIndex: 'status',
      width: 90,
      render: (s) => <Tag color={STATUS_COLORS[s] || 'default'}>{STATUS_LABELS[s] || s}</Tag>,
    },
    {
      title: '操作',
      width: 160,
      fixed: 'right',
      render: (_, row) => (
        <Space size={0}>
          <Button type="link" size="small" onClick={() => void openDetail(row.id)}>
            明细
          </Button>
          {row.status === 'UNPAID' && (
            <Button
              type="link"
              size="small"
              onClick={() => confirmPay([row.id], Number(row.logisticsAmount))}
            >
              确认结算
            </Button>
          )}
        </Space>
      ),
    },
  ];

  const summaryColumns: ColumnsType<ProviderSummary> = [
    {
      title: '承运商',
      render: (_, r) => `${r.providerName} (${r.providerCode})`,
    },
    {
      title: '结算方式',
      dataIndex: 'settlementMethod',
      width: 110,
      render: (v) =>
        LOGISTICS_SETTLEMENT_METHOD_LABELS[v as LogisticsSettlementMethod] || v,
    },
    {
      title: '计价标准',
      width: 220,
      render: (_, r) => {
        const p = r.pricingRules;
        if (!p) return '—';
        return `${p.baseBottles}瓶¥${p.baseFee}，加瓶¥${p.extraBottleFee}${
          p.boxBottles ? `，${p.boxBottles}瓶箱¥${p.boxFee}` : ''
        }`;
      },
    },
    {
      title: '银行账户',
      width: 180,
      render: (_, r) =>
        r.bankAccountName
          ? `${r.bankAccountName} / ${r.bankName || ''} ${r.bankAccountNo || ''}`
          : '—',
    },
    { title: '订单数', dataIndex: 'orderCount', width: 80 },
    { title: '瓶数', dataIndex: 'bottleCount', width: 80 },
    {
      title: '应付物流费',
      dataIndex: 'logisticsAmount',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '充值余额',
      dataIndex: 'prepaidBalance',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '账单',
      width: 100,
      render: (_, r) =>
        r.billStatus ? (
          <Tag color={STATUS_COLORS[r.billStatus] || 'default'}>
            {STATUS_LABELS[r.billStatus] || r.billStatus}
          </Tag>
        ) : (
          '未生成'
        ),
    },
    {
      title: '操作',
      width: 100,
      render: (_, r) =>
        r.settlementMethod === 'PREPAID' ? (
          <Button
            type="link"
            size="small"
            onClick={() => {
              setRechargeTarget(r);
              rechargeForm.resetFields();
              setRechargeOpen(true);
            }}
          >
            充值
          </Button>
        ) : null,
    },
  ];

  const { columns, settingsButton, settingsModal, exportColumnKeys } = useAdminListColumns('finance-logistics-bills', billColumns, {
    page,
    pageSize,
  });

  return (
    <div>
      {settingsModal}
      <AdminListHeader
        title="物流对账"
        settings={settingsButton}
        description="按快递承运商汇总月度物流费；计价与银行账户在「仓配管理」配置。前期充值扣款，后期可切挂账月结。"
      />

      <Tabs
        items={[
          {
            key: 'summary',
            label: '按承运商汇总',
            children: (
              <>
                <Form
                  form={summaryForm}
                  layout="inline"
                  style={{ marginBottom: 16 }}
                  initialValues={{ month: summaryPeriod }}
                  onFinish={(v: { month?: Dayjs }) => {
                    const m = v.month || dayjs().subtract(1, 'month');
                    setSummaryPeriod(m);
                  }}
                >
                  <Form.Item name="month" label="账期">
                    <DatePicker picker="month" allowClear={false} />
                  </Form.Item>
                  <Form.Item>
                    <Button type="primary" htmlType="submit">
                      查询
                    </Button>
                  </Form.Item>
                </Form>
                <Table
                  rowKey="providerId"
                  loading={summaryLoading}
                  columns={summaryColumns}
                  dataSource={summaryRows}
                  pagination={false}
                  scroll={{ x: 1200 }}
                />
              </>
            ),
          },
          {
            key: 'bills',
            label: '月账单',
            children: (
              <>
                {summary && (
                  <Card size="small" style={{ marginBottom: 16 }}>
                    <Space size="large" wrap>
                      <Statistic title="账单数" value={summary.count} />
                      <Statistic
                        title="瓶数合计"
                        value={summary.bottleCount ?? 0}
                      />
                      <Statistic
                        title="物流费合计"
                        value={summary.logisticsAmount ?? summary.totalAmount ?? 0}
                        prefix="¥"
                        precision={2}
                      />
                    </Space>
                  </Card>
                )}

                <Form
                  form={form}
                  layout="inline"
                  style={{ marginBottom: 16 }}
                  onFinish={(v: {
                    status?: string;
                    providerId?: string;
                    month?: Dayjs;
                  }) => {
                    setFilters({
                      status: v.status || '',
                      providerId: v.providerId || '',
                      year: v.month ? String(v.month.year()) : '',
                      month: v.month ? String(v.month.month() + 1) : '',
                    });
                    setPage(1);
                  }}
                >
                  <Form.Item name="status" label="状态">
                    <Select
                      allowClear
                      style={{ width: 120 }}
                      options={[
                        { value: 'UNPAID', label: '未结算' },
                        { value: 'PAID', label: '已结算' },
                      ]}
                    />
                  </Form.Item>
                  <Form.Item name="providerId" label="承运商">
                    <Select
                      allowClear
                      style={{ width: 180 }}
                      options={providers.map((p) => ({
                        value: p.id,
                        label: `${p.name} (${p.code})`,
                      }))}
                    />
                  </Form.Item>
                  <Form.Item name="month" label="账期">
                    <DatePicker picker="month" />
                  </Form.Item>
                  <Form.Item>
                    <Space>
                      <Button type="primary" htmlType="submit">
                        查询
                      </Button>
                      <Button
                        onClick={() => {
                          genForm.setFieldsValue({ month: dayjs().subtract(1, 'month') });
                          setGenOpen(true);
                        }}
                      >
                        生成账单
                      </Button>
                      <Button loading={exporting} onClick={() => void exportExcel()}>
                        导出
                      </Button>
                      <Button
                        disabled={!selectedKeys.length}
                        onClick={() =>
                          confirmPay(
                            selectedKeys.map(String),
                            selectedAmount,
                          )
                        }
                      >
                        批量结算
                      </Button>
                    </Space>
                  </Form.Item>
                </Form>

                <Table
                  rowKey="id"
                  loading={loading}
                  columns={columns}
                  dataSource={data?.items ?? []}
                  rowSelection={{
                    selectedRowKeys: selectedKeys,
                    onChange: setSelectedKeys,
                    getCheckboxProps: (r) => ({ disabled: r.status !== 'UNPAID' }),
                  }}
                  pagination={{
                    current: page,
                    pageSize,
                    total: data?.total ?? 0,
                    onChange: (p, ps) => {
                      setPage(p);
                      setPageSize(ps);
                    },
                  }}
                  scroll={{ x: 1100 }}
                />
              </>
            ),
          },
        ]}
      />

      <Drawer
        title="物流对账明细"
        width={640}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
      >
        {detail && (
          <>
            <Descriptions column={1} size="small" style={{ marginBottom: 16 }}>
              <Descriptions.Item label="账单号">{detail.billNo}</Descriptions.Item>
              <Descriptions.Item label="承运商">
                {detail.providerName} ({detail.providerCode})
              </Descriptions.Item>
              <Descriptions.Item label="账期">
                {String(detail.periodStart).slice(0, 10)} ~ {String(detail.periodEnd).slice(0, 10)}
              </Descriptions.Item>
              <Descriptions.Item label="物流费">
                ¥{Number(detail.logisticsAmount).toFixed(2)}
              </Descriptions.Item>
              <Descriptions.Item label="状态">
                {STATUS_LABELS[detail.status] || detail.status}
              </Descriptions.Item>
              <Descriptions.Item label="结算时间">
                {detail.paidAt ? fmtTime(detail.paidAt) : '—'}
              </Descriptions.Item>
              <Descriptions.Item label="打款凭证">
                {detail.paymentRef ? String(detail.paymentRef) : '—'}
              </Descriptions.Item>
            </Descriptions>
            {providerBank(detail) ? (
              <>
                <Typography.Title level={5} style={{ marginTop: 16 }}>
                  收款账户
                </Typography.Title>
                <Descriptions column={1} size="small" bordered style={{ marginBottom: 16 }}>
                  <Descriptions.Item label="户名">
                    {providerBank(detail)?.bankAccountName || '—'}
                  </Descriptions.Item>
                  <Descriptions.Item label="开户银行">
                    {providerBank(detail)?.bankName || '—'}
                  </Descriptions.Item>
                  <Descriptions.Item label="开户支行">
                    {providerBank(detail)?.bankBranch || '—'}
                  </Descriptions.Item>
                  <Descriptions.Item label="账号">
                    {providerBank(detail)?.bankAccountNo || '—'}
                  </Descriptions.Item>
                </Descriptions>
              </>
            ) : null}
            <Table
              rowKey="id"
              size="small"
              pagination={false}
              dataSource={detail.items ?? []}
              columns={[
                {
                  title: '订单号',
                  dataIndex: 'orderNo',
                  render: (v: string) =>
                    v ? (
                      <AdminPrimaryLink
                        onClick={() => navigate(`/orders?orderNo=${encodeURIComponent(v)}`)}
                      >
                        {v}
                      </AdminPrimaryLink>
                    ) : (
                      '—'
                    ),
                },
                { title: '瓶数', dataIndex: 'quantity', width: 70 },
                {
                  title: '物流费',
                  dataIndex: 'logisticsAmount',
                  width: 90,
                  render: (v) => `¥${Number(v).toFixed(2)}`,
                },
                {
                  title: '发货时间',
                  dataIndex: 'shippedAt',
                  width: 160,
                  render: fmtTime,
                },
              ]}
            />
          </>
        )}
      </Drawer>

      <Modal
        title="生成物流月账单"
        open={genOpen}
        onCancel={() => setGenOpen(false)}
        onOk={() => void generateBills()}
        destroyOnClose
      >
        <Form form={genForm} layout="vertical">
          <Form.Item name="month" label="账期月" rules={[{ required: true }]}>
            <DatePicker picker="month" style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="providerId" label="承运商（空=全部）">
            <Select
              allowClear
              options={providers.map((p) => ({
                value: p.id,
                label: `${p.name} (${p.code})`,
              }))}
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={rechargeTarget ? `充值 · ${rechargeTarget.providerName}` : '充值'}
        open={rechargeOpen}
        onCancel={() => setRechargeOpen(false)}
        onOk={() => void submitRecharge()}
        destroyOnClose
      >
        <Form form={rechargeForm} layout="vertical">
          <Form.Item
            name="amount"
            label="金额"
            rules={[{ required: true, message: '请输入充值金额' }]}
          >
            <InputNumber min={0.01} precision={2} style={{ width: '100%' }} prefix="¥" />
          </Form.Item>
          <Form.Item name="remark" label="备注">
            <Input placeholder="可选，如预充运费" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}
