import { useEffect, useState } from 'react';
import {
  Button,
  Card,
  DatePicker,
  Descriptions,
  Drawer,
  Form,
  Input,
  Modal,
  Select,
  Space,
  Statistic,
  Table,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { Dayjs } from 'dayjs';
import {
  WINERY_SETTLEMENT_RATE,
  type SystemConfigFormResponse,
} from '@dukang/shared-types';
import { fmtTime } from '../lib/constants';
import { downloadExcelCsv } from '../lib/exportExcel';
import { request, type HqProfile } from '../lib/api';
import { useAdminList } from '../lib/useAdminList';

type Row = {
  id: string;
  billNo: string;
  billDate: string;
  orderCount: number;
  orderAmount: number;
  wineryRate: number;
  wineryAmount: number;
  status: string;
  paidAt?: string | null;
};

type BillItem = {
  id: string;
  orderNo: string;
  deliveryType: string;
  payAmount: number;
  wineryAmount: number;
  paidAt: string;
};

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

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

const DELIVERY_LABELS: Record<string, string> = {
  LOCAL: '同城',
  CROSS_CITY: '跨城',
};

const WINERY_BANK_KEYS = [
  'WINERY_BANK_ACCOUNT_NAME',
  'WINERY_BANK_NAME',
  'WINERY_BANK_BRANCH',
  'WINERY_BANK_ACCOUNT_NO',
] as const;

export default function WineryBillsPage() {
  const [form] = Form.useForm();
  const [bankForm] = Form.useForm<Record<string, string>>();
  const [filters, setFilters] = useState<Record<string, string>>({});
  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<Row>(
    '/admin/winery-bills',
    () => {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      if (filters.year) qs.set('year', filters.year);
      if (filters.month) qs.set('month', filters.month);
      if (filters.dateFrom) qs.set('dateFrom', filters.dateFrom);
      if (filters.dateTo) qs.set('dateTo', filters.dateTo);
      return qs;
    },
    [filters],
  );
  const [exporting, setExporting] = useState(false);
  const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
  const [detail, setDetail] = useState<(Row & { items?: BillItem[] }) | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [profile, setProfile] = useState<HqProfile | null>(null);
  const [bankOpen, setBankOpen] = useState(false);
  const [bankLoading, setBankLoading] = useState(false);
  const [bankSaving, setBankSaving] = useState(false);

  useEffect(() => {
    request<HqProfile>('/admin/auth/me').then(setProfile).catch(() => {});
  }, []);

  const canEditWineryBank =
    profile?.adminRole === 'SUPER_ADMIN' ||
    (profile?.permissionKeys ?? []).includes('system_settings_winery_bank');

  function confirmPay(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/winery-bills/${ids[0]}/confirm`, { method: 'POST' });
        } else {
          await request('/admin/winery-bills/batch-confirm', {
            method: 'POST',
            body: JSON.stringify({ ids }),
          });
        }
        message.success('已确认打款');
        setSelectedKeys([]);
        reload();
      },
    });
  }

  async function openDetail(id: string) {
    const d = await request<Row & { items?: BillItem[] }>(`/admin/winery-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.year) qs.set('year', filters.year);
      if (filters.month) qs.set('month', filters.month);
      if (filters.dateFrom) qs.set('dateFrom', filters.dateFrom);
      if (filters.dateTo) qs.set('dateTo', filters.dateTo);
      const result = await request<{ csv: string; count: number }>(`/admin/winery-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 openBankModal() {
    setBankOpen(true);
    setBankLoading(true);
    try {
      const cfg = await request<SystemConfigFormResponse>('/admin/system-config');
      const values: Record<string, string> = {};
      for (const key of WINERY_BANK_KEYS) {
        values[key] = cfg.values[key] ?? '';
      }
      bankForm.setFieldsValue(values);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '加载失败');
      setBankOpen(false);
    } finally {
      setBankLoading(false);
    }
  }

  async function saveBank() {
    const values = await bankForm.validateFields();
    setBankSaving(true);
    try {
      await request('/admin/system-config', {
        method: 'PUT',
        body: JSON.stringify({ values }),
      });
      message.success('酒厂银行账户已保存');
      setBankOpen(false);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '保存失败');
    } finally {
      setBankSaving(false);
    }
  }

  const summary = data?.summary;
  const ratePct = Math.round(WINERY_SETTLEMENT_RATE * 100);
  const selectedRows = (data?.items ?? []).filter((r) => selectedKeys.includes(r.id));
  const selectedAmount = selectedRows.reduce((s, r) => s + Number(r.wineryAmount), 0);

  const columns: ColumnsType<Row> = [
    { title: '账单号', dataIndex: 'billNo', width: 170, ellipsis: true },
    {
      title: '账单日',
      dataIndex: 'billDate',
      width: 110,
      render: (v) => String(v || '').slice(0, 10),
    },
    { title: '订单数', dataIndex: 'orderCount', width: 80 },
    {
      title: '酒单实付合计',
      dataIndex: 'orderAmount',
      width: 120,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '酒厂比例',
      dataIndex: 'wineryRate',
      width: 90,
      render: (v) => `${Math.round(Number(v) * 100)}%`,
    },
    {
      title: '酒厂应付',
      dataIndex: 'wineryAmount',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '状态',
      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.wineryAmount))}>
              确认打款
            </Button>
          )}
        </Space>
      ),
    },
  ];

  return (
    <div>
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'flex-start',
          marginBottom: 16,
          gap: 16,
        }}
      >
        <Space direction="vertical" size={0}>
          <Typography.Title level={4} style={{ margin: 0 }}>
            酒厂对账单
          </Typography.Title>
          <Typography.Text type="secondary">
            每日 8:00 汇总昨日已付订单（实付 × {ratePct}%）；未打款红色、已打款绿色，可展开订单明细
          </Typography.Text>
        </Space>
        {canEditWineryBank ? (
          <Button type="default" onClick={() => void openBankModal()}>
            酒厂银行账户信息配置
          </Button>
        ) : null}
      </div>

      {summary && (
        <Card size="small" style={{ marginBottom: 16 }}>
          <Space size="large" wrap>
            <Statistic title="账单数" value={summary.count} />
            <Statistic title="酒单实付合计" value={summary.orderAmount ?? 0} prefix="¥" precision={2} />
            <Statistic title="酒厂应付合计" value={summary.wineryAmount ?? 0} prefix="¥" precision={2} />
          </Space>
        </Card>
      )}

      <Form
        form={form}
        layout="inline"
        style={{ marginBottom: 16 }}
        onFinish={(v: { status?: string; month?: Dayjs; range?: [Dayjs, Dayjs] }) => {
          setFilters({
            status: v.status || '',
            year: v.month ? String(v.month.year()) : '',
            month: v.month ? String(v.month.month() + 1) : '',
            dateFrom: v.range?.[0] ? v.range[0].format('YYYY-MM-DD') : '',
            dateTo: v.range?.[1] ? v.range[1].format('YYYY-MM-DD') : '',
          });
          setPage(1);
        }}
      >
        <Form.Item name="status" label="状态">
          <Select
            allowClear
            style={{ width: 120 }}
            options={Object.entries(STATUS_LABELS).map(([value, label]) => ({ value, label }))}
          />
        </Form.Item>
        <Form.Item name="month" label="账期月">
          <DatePicker picker="month" />
        </Form.Item>
        <Form.Item name="range" label="账单日">
          <DatePicker.RangePicker />
        </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 loading={exporting} onClick={() => void exportExcel()}>
            导出 Excel
          </Button>
        </Form.Item>
        <Form.Item>
          <Button
            type="primary"
            disabled={!selectedKeys.length}
            onClick={() => confirmPay(selectedKeys.map(String), selectedAmount)}
          >
            批量确认打款 ({selectedKeys.length})
          </Button>
        </Form.Item>
      </Form>

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

      <Drawer title="酒厂对账单明细" open={drawerOpen} onClose={() => setDrawerOpen(false)} width={640}>
        {detail && (
          <>
            <Descriptions column={1} size="small" bordered>
              <Descriptions.Item label="账单号">{detail.billNo}</Descriptions.Item>
              <Descriptions.Item label="账单日">{String(detail.billDate).slice(0, 10)}</Descriptions.Item>
              <Descriptions.Item label="酒厂应付">¥{Number(detail.wineryAmount).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>
            <Typography.Title level={5} style={{ marginTop: 16 }}>
              订单明细
            </Typography.Title>
            <Table
              size="small"
              rowKey="id"
              pagination={false}
              dataSource={detail.items ?? []}
              columns={[
                { title: '订单号', dataIndex: 'orderNo', ellipsis: true },
                {
                  title: '配送',
                  dataIndex: 'deliveryType',
                  width: 70,
                  render: (v) => DELIVERY_LABELS[v] || v,
                },
                {
                  title: '实付',
                  dataIndex: 'payAmount',
                  width: 90,
                  render: (v) => `¥${Number(v).toFixed(2)}`,
                },
                {
                  title: '酒厂应付',
                  dataIndex: 'wineryAmount',
                  width: 90,
                  render: (v) => `¥${Number(v).toFixed(2)}`,
                },
                {
                  title: '支付时间',
                  dataIndex: 'paidAt',
                  width: 150,
                  render: (v) => (v ? fmtTime(v) : '—'),
                },
              ]}
            />
          </>
        )}
      </Drawer>

      <Modal
        title="酒厂银行账户信息配置"
        open={bankOpen}
        onCancel={() => setBankOpen(false)}
        onOk={() => void saveBank()}
        confirmLoading={bankSaving}
        destroyOnClose
        okText="保存"
      >
        <Form form={bankForm} layout="vertical" disabled={bankLoading}>
          <Form.Item
            name="WINERY_BANK_ACCOUNT_NAME"
            label="户名"
            rules={[{ required: true, message: '请填写户名' }]}
          >
            <Input placeholder="收款账户户名" />
          </Form.Item>
          <Form.Item
            name="WINERY_BANK_NAME"
            label="开户银行"
            rules={[{ required: true, message: '请填写开户银行' }]}
          >
            <Input placeholder="如：中国工商银行" />
          </Form.Item>
          <Form.Item name="WINERY_BANK_BRANCH" label="开户支行">
            <Input placeholder="可选" />
          </Form.Item>
          <Form.Item
            name="WINERY_BANK_ACCOUNT_NO"
            label="银行账号"
            rules={[{ required: true, message: '请填写银行账号' }]}
          >
            <Input placeholder="银行卡号" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}
