import { useState } from 'react';
import {
  Button,
  Descriptions,
  Drawer,
  Form,
  Input,
  Select,
  Table,
  Tag,
  Typography,
  Upload,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  INVOICE_KIND_LABELS,
  INVOICE_STATUS_LABELS,
  INVOICE_TITLE_TYPE_LABELS,
  type InvoiceKind,
  type InvoiceStatus,
  type InvoiceTitleType,
} from '@dukang/shared-types';
import { request } from '../lib/api';
import { fmtTime } from '../lib/constants';
import { useAdminList } from '../lib/useAdminList';
import { uploadFileToOss } from '../lib/upload';

type Row = {
  id: string;
  invoiceNo: string;
  orderNo?: string;
  titleType: InvoiceTitleType;
  invoiceKind: InvoiceKind;
  titleName: string;
  status: InvoiceStatus;
  overdue?: boolean;
  createdAt: string;
  fileUrl?: string;
  email?: string;
  phone?: string;
  taxNo?: string;
  addressPhone?: string;
  bankAccount?: string;
  payAmount?: string;
  userPhone?: string;
  remark?: string;
};

export default function InvoicesPage() {
  const [filters, setFilters] = useState<Record<string, string>>({});
  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<Row>(
    '/admin/invoices',
    () => {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      return qs;
    },
    [filters],
  );
  const [detail, setDetail] = useState<Row | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [uploading, setUploading] = useState(false);

  async function openDetail(id: string) {
    setDetail(await request(`/admin/invoices/${id}`));
    setDrawerOpen(true);
  }

  async function issueWithFile(file: File) {
    if (!detail) return false;
    setUploading(true);
    try {
      const uploaded = await uploadFileToOss(file, { bizType: 'invoice' });
      await request(`/admin/invoices/${detail.id}/issue`, {
        method: 'POST',
        body: JSON.stringify({ fileUrl: uploaded.url }),
      });
      message.success('已开票回传');
      reload();
      setDrawerOpen(false);
    } catch (e) {
      message.error(e instanceof Error ? e.message : '开票失败');
    } finally {
      setUploading(false);
    }
    return false;
  }

  async function reject() {
    if (!detail) return;
    await request(`/admin/invoices/${detail.id}/reject`, {
      method: 'POST',
      body: JSON.stringify({ remark: '驳回' }),
    });
    message.success('已驳回');
    reload();
    setDrawerOpen(false);
  }

  const columns: ColumnsType<Row> = [
    { title: '申请单号', dataIndex: 'invoiceNo', width: 180 },
    { title: '订单号', dataIndex: 'orderNo', width: 160 },
    {
      title: '抬头',
      width: 100,
      render: (_, r) => INVOICE_TITLE_TYPE_LABELS[r.titleType] ?? r.titleType,
    },
    {
      title: '票种',
      width: 120,
      render: (_, r) => INVOICE_KIND_LABELS[r.invoiceKind] ?? r.invoiceKind,
    },
    { title: '名称', dataIndex: 'titleName', ellipsis: true },
    {
      title: '状态',
      width: 110,
      render: (_, r) => (
        <>
          <Tag color={r.status === 'ISSUED' ? 'green' : r.status === 'REJECTED' ? 'red' : 'orange'}>
            {INVOICE_STATUS_LABELS[r.status] ?? r.status}
          </Tag>
          {r.overdue ? <Tag color="red">超时</Tag> : null}
        </>
      ),
    },
    { title: '申请时间', dataIndex: 'createdAt', width: 160, render: fmtTime },
    {
      title: '操作',
      width: 80,
      render: (_, row) => (
        <Button type="link" size="small" onClick={() => openDetail(row.id)}>
          详情
        </Button>
      ),
    },
  ];

  return (
    <div>
      <Typography.Title level={4}>发票管理</Typography.Title>
      <Form
        layout="inline"
        style={{ marginBottom: 16 }}
        onFinish={(v) => {
          setFilters(v);
          setPage(1);
        }}
      >
        <Form.Item name="status" label="状态">
          <Select
            allowClear
            style={{ width: 120 }}
            options={[
              { value: 'PENDING', label: '待开票' },
              { value: 'ISSUED', label: '已开票' },
              { value: 'REJECTED', label: '已驳回' },
            ]}
          />
        </Form.Item>
        <Button type="primary" htmlType="submit">
          筛选
        </Button>
      </Form>
      <Table
        rowKey="id"
        loading={loading}
        columns={columns}
        dataSource={data?.items ?? []}
        scroll={{ x: 1000 }}
        rowClassName={(r) => (r.overdue ? 'ant-table-row-overdue' : '')}
        pagination={{
          current: page,
          pageSize,
          total: data?.total ?? 0,
          showSizeChanger: true,
          onChange: (p, ps) => {
            setPage(p);
            setPageSize(ps);
          },
        }}
      />
      <Drawer
        title="发票详情"
        width={520}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        extra={
          detail?.status === 'PENDING' ? (
            <>
              <Upload
                accept="image/*,.pdf"
                showUploadList={false}
                beforeUpload={(file) => {
                  void issueWithFile(file);
                  return false;
                }}
              >
                <Button type="primary" loading={uploading} style={{ marginRight: 8 }}>
                  上传并开票
                </Button>
              </Upload>
              <Button danger onClick={() => void reject()}>
                驳回
              </Button>
            </>
          ) : null
        }
      >
        {detail && (
          <Descriptions column={1} bordered size="small">
            <Descriptions.Item label="申请单号">{detail.invoiceNo}</Descriptions.Item>
            <Descriptions.Item label="订单号">{detail.orderNo ?? '—'}</Descriptions.Item>
            <Descriptions.Item label="金额">{detail.payAmount ?? '—'}</Descriptions.Item>
            <Descriptions.Item label="用户手机">{detail.userPhone ?? '—'}</Descriptions.Item>
            <Descriptions.Item label="抬头类型">
              {INVOICE_TITLE_TYPE_LABELS[detail.titleType]}
            </Descriptions.Item>
            <Descriptions.Item label="发票类型">
              {INVOICE_KIND_LABELS[detail.invoiceKind]}
            </Descriptions.Item>
            <Descriptions.Item label="抬头名称">{detail.titleName}</Descriptions.Item>
            <Descriptions.Item label="税号">{detail.taxNo ?? '—'}</Descriptions.Item>
            <Descriptions.Item label="地址电话">{detail.addressPhone ?? '—'}</Descriptions.Item>
            <Descriptions.Item label="开户行账号">{detail.bankAccount ?? '—'}</Descriptions.Item>
            <Descriptions.Item label="邮箱">{detail.email}</Descriptions.Item>
            <Descriptions.Item label="手机">{detail.phone}</Descriptions.Item>
            <Descriptions.Item label="状态">
              {INVOICE_STATUS_LABELS[detail.status]}
              {detail.overdue ? '（超 2 工作日）' : ''}
            </Descriptions.Item>
            <Descriptions.Item label="发票文件">
              {detail.fileUrl ? (
                <a href={detail.fileUrl} target="_blank" rel="noreferrer">
                  查看/下载
                </a>
              ) : (
                '—'
              )}
            </Descriptions.Item>
            <Descriptions.Item label="备注">{detail.remark ?? '—'}</Descriptions.Item>
          </Descriptions>
        )}
      </Drawer>
    </div>
  );
}
