import { useEffect, useRef, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import {
  Button,
  Descriptions,
  Drawer,
  Form,
  Input,
  Modal,
  Select,
  Space,
  Table,
  Tag,
  Typography,
  Upload,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  INVOICE_CATEGORY_LABELS,
  INVOICE_KIND_LABELS,
  INVOICE_STATUS_LABELS,
  INVOICE_TITLE_TYPE_LABELS,
  type InvoiceCategory,
  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;
  invoiceCategory?: InvoiceCategory;
  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;
};

type CreateFormValues = {
  orderNo: string;
  titleType: InvoiceTitleType;
  invoiceKind: InvoiceKind;
  invoiceCategory?: InvoiceCategory;
  titleName: string;
  taxNo?: string;
  addressPhone?: string;
  bankAccount?: string;
  email: string;
  phone: string;
  remark?: string;
};

export default function InvoicesPage() {
  const [searchParams] = useSearchParams();
  const initialStatus = searchParams.get('status')?.trim() || '';
  const initialInvoiceNo = searchParams.get('invoiceNo')?.trim() || '';
  const [filterForm] = Form.useForm();
  const [filters, setFilters] = useState<Record<string, string>>(() => {
    const init: Record<string, string> = {};
    if (initialStatus) init.status = initialStatus;
    if (initialInvoiceNo) init.invoiceNo = initialInvoiceNo;
    return init;
  });
  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<Row>(
    '/admin/invoices',
    () => {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      if (filters.invoiceNo) qs.set('invoiceNo', filters.invoiceNo);
      return qs;
    },
    [filters],
  );
  const [detail, setDetail] = useState<Row | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [createOpen, setCreateOpen] = useState(false);
  const [creating, setCreating] = useState(false);
  const [createForm] = Form.useForm<CreateFormValues>();
  const invoiceKind = Form.useWatch('invoiceKind', createForm);
  const titleType = Form.useWatch('titleType', createForm);
  const deepLinkOpenedRef = useRef(false);

  useEffect(() => {
    filterForm.setFieldsValue({
      status: filters.status || undefined,
      invoiceNo: filters.invoiceNo || undefined,
    });
  }, [filterForm, filters.invoiceNo, filters.status]);

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

  useEffect(() => {
    if (!initialInvoiceNo || deepLinkOpenedRef.current || loading) return;
    const first = data?.items?.[0];
    if (first && String(first.invoiceNo) === initialInvoiceNo) {
      deepLinkOpenedRef.current = true;
      void openDetail(first.id);
    }
  }, [data, initialInvoiceNo, loading]);

  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);
  }

  async function submitCreate() {
    const values = await createForm.validateFields();
    setCreating(true);
    try {
      await request('/admin/invoices', {
        method: 'POST',
        body: JSON.stringify({
          orderNo: values.orderNo.trim(),
          titleType: values.titleType,
          invoiceKind: values.invoiceKind,
          invoiceCategory: values.invoiceCategory,
          titleName: values.titleName.trim(),
          taxNo: values.taxNo?.trim() || undefined,
          addressPhone: values.addressPhone?.trim() || undefined,
          bankAccount: values.bankAccount?.trim() || undefined,
          email: values.email.trim(),
          phone: values.phone.trim(),
          remark: values.remark?.trim() || undefined,
        }),
      });
      message.success('发票申请已创建');
      setCreateOpen(false);
      createForm.resetFields();
      reload();
    } catch (e) {
      message.error(e instanceof Error ? e.message : '创建失败');
    } finally {
      setCreating(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: 140,
      render: (_, r) => INVOICE_KIND_LABELS[r.invoiceKind] ?? r.invoiceKind,
    },
    {
      title: '类型',
      width: 88,
      render: (_, r) =>
        r.invoiceCategory
          ? INVOICE_CATEGORY_LABELS[r.invoiceCategory] ?? r.invoiceCategory
          : '—',
    },
    { 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>
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          marginBottom: 16,
        }}
      >
        <Typography.Title level={4} style={{ margin: 0 }}>
          发票管理
        </Typography.Title>
        <Button
          type="primary"
          onClick={() => {
            createForm.setFieldsValue({
              titleType: 'PERSONAL',
              invoiceKind: 'NORMAL',
              invoiceCategory: 'LIQUOR',
            });
            setCreateOpen(true);
          }}
        >
          创建发票申请
        </Button>
      </div>
      <Form
        form={filterForm}
        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>
        <Form.Item name="invoiceNo" label="申请单号">
          <Input allowClear placeholder="发票申请单号" />
        </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' ? (
            <Space>
              <Upload
                accept="image/*,.pdf"
                showUploadList={false}
                beforeUpload={(file) => {
                  void issueWithFile(file);
                  return false;
                }}
              >
                <Button type="primary" loading={uploading}>
                  上传并开票
                </Button>
              </Upload>
              <Button danger onClick={() => void reject()}>
                驳回
              </Button>
            </Space>
          ) : 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.invoiceCategory
                ? INVOICE_CATEGORY_LABELS[detail.invoiceCategory]
                : '—'}
            </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>

      <Modal
        title="创建发票申请"
        open={createOpen}
        onCancel={() => setCreateOpen(false)}
        onOk={() => void submitCreate()}
        confirmLoading={creating}
        destroyOnClose
        okText="提交"
        width={520}
      >
        <Form form={createForm} layout="vertical">
          <Form.Item
            name="orderNo"
            label="订单号"
            rules={[{ required: true, message: '请填写已完成订单号' }]}
            extra="仅已完成订单可开票"
          >
            <Input placeholder="订单号" allowClear />
          </Form.Item>
          <Form.Item
            name="invoiceKind"
            label="发票类型"
            rules={[{ required: true, message: '请选择发票类型' }]}
          >
            <Select
              options={(Object.keys(INVOICE_KIND_LABELS) as InvoiceKind[]).map((k) => ({
                value: k,
                label: INVOICE_KIND_LABELS[k],
              }))}
              onChange={(k: InvoiceKind) => {
                if (k === 'SPECIAL') createForm.setFieldValue('titleType', 'ENTERPRISE');
              }}
            />
          </Form.Item>
          <Form.Item
            name="invoiceCategory"
            label="类型"
            rules={[{ required: true, message: '请选择类型' }]}
          >
            <Select
              options={(Object.keys(INVOICE_CATEGORY_LABELS) as InvoiceCategory[]).map((k) => ({
                value: k,
                label: INVOICE_CATEGORY_LABELS[k],
              }))}
            />
          </Form.Item>
          <Form.Item
            name="titleType"
            label="抬头类型"
            rules={[{ required: true, message: '请选择抬头类型' }]}
          >
            <Select
              options={(Object.keys(INVOICE_TITLE_TYPE_LABELS) as InvoiceTitleType[]).map((t) => ({
                value: t,
                label: INVOICE_TITLE_TYPE_LABELS[t],
                disabled: invoiceKind === 'SPECIAL' && t === 'PERSONAL',
              }))}
            />
          </Form.Item>
          <Form.Item
            name="titleName"
            label="抬头名称"
            rules={[{ required: true, message: '请填写抬头名称' }]}
          >
            <Input placeholder="个人姓名或企业全称" />
          </Form.Item>
          {(titleType === 'ENTERPRISE' || invoiceKind === 'SPECIAL') && (
            <Form.Item
              name="taxNo"
              label="税号"
              rules={[{ required: true, message: '企业抬头须填写税号' }]}
            >
              <Input placeholder="纳税人识别号" />
            </Form.Item>
          )}
          {invoiceKind === 'SPECIAL' && (
            <>
              <Form.Item
                name="addressPhone"
                label="地址电话"
                rules={[{ required: true, message: '专用发票须填写地址电话' }]}
              >
                <Input placeholder="注册地址及电话" />
              </Form.Item>
              <Form.Item
                name="bankAccount"
                label="开户行账号"
                rules={[{ required: true, message: '专用发票须填写开户行账号' }]}
              >
                <Input placeholder="开户行及账号" />
              </Form.Item>
            </>
          )}
          <Form.Item
            name="email"
            label="接收邮箱"
            rules={[
              { required: true, message: '请填写邮箱' },
              { type: 'email', message: '邮箱格式不正确' },
            ]}
          >
            <Input placeholder="发票发送邮箱" />
          </Form.Item>
          <Form.Item
            name="phone"
            label="手机号"
            rules={[{ required: true, message: '请填写手机号' }]}
          >
            <Input placeholder="联系手机" />
          </Form.Item>
          <Form.Item name="remark" label="备注">
            <Input.TextArea rows={2} maxLength={512} showCount />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}
