import { useEffect, useState } from 'react';
import {
  Button,
  DatePicker,
  Descriptions,
  Drawer,
  Form,
  Input,
  Modal,
  Select,
  Space,
  Table,
  Tag,
  Typography,
  message,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import type { Dayjs } from 'dayjs';
import { STORE_WITHDRAW_STATUS_LABELS, type StoreWithdrawStatus } from '@dukang/shared-types';
import { request, type Paginated } from '../lib/api';
import { ADMIN_OPTIONS_PAGE_SIZE, fmtTime } from '../lib/constants';
import { useAdminList } from '../lib/useAdminList';
import { useAdminListColumns } from '../lib/useAdminListColumns';


type Row = {
  id: string;
  withdrawNo: string;
  amount: number;
  payoutCount: number;
  status: StoreWithdrawStatus;
  appliedAt: string;
  reviewedAt?: string | null;
  paidAt?: string | null;
  paymentRef?: string | null;
  rejectReason?: string | null;
  overdue?: boolean;
  store?: { id: string; name: string; cityName: string; phone?: string };
};

type StoreOption = { id: string; name: string; phone: string };

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

export default function StoreWithdrawalsPage() {
  const [form] = Form.useForm();
  const [filters, setFilters] = useState<Record<string, string>>({ status: 'PENDING_REVIEW' });
  const [stores, setStores] = useState<StoreOption[]>([]);
  const { data, loading, page, pageSize, setPage, setPageSize, reload } = useAdminList<Row>(
    '/admin/store-withdrawals',
    () => {
      const qs = new URLSearchParams();
      if (filters.status) qs.set('status', filters.status);
      if (filters.storeId) qs.set('storeId', filters.storeId);
      if (filters.dateFrom) qs.set('dateFrom', filters.dateFrom);
      if (filters.dateTo) qs.set('dateTo', filters.dateTo);
      return qs;
    },
    [filters],
  );
  const [detail, setDetail] = useState<Record<string, unknown> | null>(null);
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [overdueSummary, setOverdueSummary] = useState<{
    pendingCount: number;
    overdueCount: number;
  } | null>(null);

  useEffect(() => {
    void request<Paginated<StoreOption>>(`/admin/stores?pageSize=${ADMIN_OPTIONS_PAGE_SIZE}`)
      .then((res) => setStores(res.items))
      .catch(() => {});
    void request<{ pendingCount: number; overdueCount: number }>(
      '/admin/store-withdrawals/overdue-summary',
    )
      .then(setOverdueSummary)
      .catch(() => {});
  }, []);

  async function openDetail(id: string) {
    const d = await request<Record<string, unknown>>(`/admin/store-withdrawals/${id}`);
    setDetail(d);
    setDrawerOpen(true);
  }

  function approve(id: string) {
    let paymentRef = '';
    Modal.confirm({
      title: '审核通过并标记已结算？',
      content: (
        <Input
          placeholder="打款凭证号（可选）"
          onChange={(e) => {
            paymentRef = e.target.value;
          }}
        />
      ),
      okText: '通过并结算',
      cancelText: '取消',
      onOk: async () => {
        await request(`/admin/store-withdrawals/${id}/approve`, {
          method: 'POST',
          body: JSON.stringify({ paymentRef: paymentRef.trim() || undefined }),
        });
        message.success('已通过并标记已结算');
        setDrawerOpen(false);
        reload();
        void request<{ pendingCount: number; overdueCount: number }>(
          '/admin/store-withdrawals/overdue-summary',
        )
          .then(setOverdueSummary)
          .catch(() => {});
      },
    });
  }

  function reject(id: string) {
    let reason = '';
    Modal.confirm({
      title: '驳回提现申请？',
      content: (
        <Input.TextArea
          rows={3}
          placeholder="请填写驳回理由"
          onChange={(e) => {
            reason = e.target.value;
          }}
        />
      ),
      okText: '确认驳回',
      okButtonProps: { danger: true },
      cancelText: '取消',
      onOk: async () => {
        if (!reason.trim()) {
          message.error('请填写驳回理由');
          throw new Error('reason required');
        }
        await request(`/admin/store-withdrawals/${id}/reject`, {
          method: 'POST',
          body: JSON.stringify({ reason: reason.trim() }),
        });
        message.success('已驳回');
        setDrawerOpen(false);
        reload();
      },
    });
  }

  const baseColumns: ColumnsType<Row> = [
    {
      title: '提现单号',
      dataIndex: 'withdrawNo',
      width: 180,
      render: (v, row) => (
        <Space>
          <Typography.Link onClick={() => void openDetail(row.id)}>{v}</Typography.Link>
          {row.overdue ? <Tag color="magenta">超时</Tag> : null}
        </Space>
      ),
    },
    {
      title: '门店',
      dataIndex: ['store', 'name'],
      width: 160,
      render: (_, row) => (
        <div>
          <div>{row.store?.name || '—'}</div>
          <Typography.Text type="secondary" style={{ fontSize: 12 }}>
            {row.store?.cityName} {row.store?.phone}
          </Typography.Text>
        </div>
      ),
    },
    {
      title: '金额',
      dataIndex: 'amount',
      width: 110,
      render: (v) => `¥${Number(v).toFixed(2)}`,
    },
    { title: '明细笔数', dataIndex: 'payoutCount', width: 90 },
    {
      title: '状态',
      dataIndex: 'status',
      width: 100,
      render: (v: StoreWithdrawStatus) => (
        <Tag color={STATUS_COLORS[v]}>{STORE_WITHDRAW_STATUS_LABELS[v] ?? v}</Tag>
      ),
    },
    {
      title: '申请时间',
      dataIndex: 'appliedAt',
      width: 170,
      render: (v) => fmtTime(v),
    },
    {
      title: '操作',
      key: 'actions',
      width: 180,
      fixed: 'right',
      render: (_, row) => (
        <Space>
          <Button size="small" onClick={() => void openDetail(row.id)}>
            详情
          </Button>
          {row.status === 'PENDING_REVIEW' ? (
            <>
              <Button size="small" type="primary" onClick={() => approve(row.id)}>
                通过
              </Button>
              <Button size="small" danger onClick={() => reject(row.id)}>
                驳回
              </Button>
            </>
          ) : null}
        </Space>
      ),
    },
  ];

  const detailItems = (detail?.items as Array<Record<string, unknown>> | undefined) ?? [];
  const storeAccount = detail?.storeAccount as
    | {
        name?: string;
        phone?: string;
        bankAccountName?: string;
        bankAccountNo?: string;
        bankBranch?: string;
      }
    | undefined;

  const { columns, settingsButton, settingsModal } = useAdminListColumns('finance-store-withdrawals', baseColumns, { page, pageSize });

  return (
    <div>
      {settingsModal}
      <Typography.Title level={4} style={{ marginTop: 0 }}>
        门店提现审
      </Typography.Title>
          {settingsButton}
      {overdueSummary ? (
        <Typography.Paragraph type="secondary">
          待审 {overdueSummary.pendingCount} 笔
          {overdueSummary.overdueCount > 0 ? (
            <Typography.Text type="danger">
              {' '}
              · 超时未审 {overdueSummary.overdueCount} 笔（FIN-003）
            </Typography.Text>
          ) : null}
        </Typography.Paragraph>
      ) : null}

      <Form
        form={form}
        layout="inline"
        style={{ marginBottom: 16, gap: 8 }}
        initialValues={{ status: 'PENDING_REVIEW' }}
        onFinish={(v) => {
          const range = v.range as [Dayjs, Dayjs] | undefined;
          setFilters({
            status: v.status || '',
            storeId: v.storeId || '',
            dateFrom: range?.[0]?.format('YYYY-MM-DD') || '',
            dateTo: range?.[1]?.format('YYYY-MM-DD') || '',
          });
        }}
      >
        <Form.Item name="status" label="状态">
          <Select
            allowClear
            style={{ width: 140 }}
            options={[
              { value: 'PENDING_REVIEW', label: '待审核' },
              { value: 'PAID', label: '已结算' },
              { value: 'REJECTED', label: '已驳回' },
            ]}
          />
        </Form.Item>
        <Form.Item name="storeId" label="门店">
          <Select
            allowClear
            showSearch
            optionFilterProp="label"
            style={{ width: 220 }}
            options={stores.map((s) => ({
              value: s.id,
              label: `${s.name} (${s.phone})`,
            }))}
          />
        </Form.Item>
        <Form.Item name="range" label="申请日">
          <DatePicker.RangePicker />
        </Form.Item>
        <Form.Item>
          <Button type="primary" htmlType="submit">
            查询
          </Button>
        </Form.Item>
      </Form>

      <Table
        rowKey="id"
        loading={loading}
        columns={columns}
        dataSource={data?.items ?? []}
        scroll={{ x: 'max-content' }}
        rowClassName={(row) => (row.overdue ? 'ant-table-row-selected' : '')}
        pagination={{
          current: page,
          pageSize,
          total: data?.total ?? 0,
          showSizeChanger: true,
          onChange: (p, ps) => {
            setPage(p);
            setPageSize(ps);
          },
        }}
      />

      <Drawer
        title="提现详情"
        width={640}
        open={drawerOpen}
        onClose={() => setDrawerOpen(false)}
        extra={
          detail?.status === 'PENDING_REVIEW' ? (
            <Space>
              <Button type="primary" onClick={() => approve(String(detail.id))}>
                通过
              </Button>
              <Button danger onClick={() => reject(String(detail.id))}>
                驳回
              </Button>
            </Space>
          ) : null
        }
      >
        {detail ? (
          <>
            <Descriptions column={1} size="small" bordered>
              <Descriptions.Item label="提现单号">{String(detail.withdrawNo)}</Descriptions.Item>
              <Descriptions.Item label="状态">
                <Tag color={STATUS_COLORS[String(detail.status)]}>
                  {STORE_WITHDRAW_STATUS_LABELS[detail.status as StoreWithdrawStatus] ??
                    String(detail.status)}
                </Tag>
                {detail.overdue ? <Tag color="magenta">超时</Tag> : null}
              </Descriptions.Item>
              <Descriptions.Item label="金额">¥{Number(detail.amount).toFixed(2)}</Descriptions.Item>
              <Descriptions.Item label="明细笔数">{String(detail.payoutCount)}</Descriptions.Item>
              <Descriptions.Item label="申请时间">{fmtTime(String(detail.appliedAt))}</Descriptions.Item>
              {detail.rejectReason ? (
                <Descriptions.Item label="驳回理由">{String(detail.rejectReason)}</Descriptions.Item>
              ) : null}
              {detail.paymentRef ? (
                <Descriptions.Item label="打款凭证">{String(detail.paymentRef)}</Descriptions.Item>
              ) : null}
              <Descriptions.Item label="收款户名">
                {storeAccount?.bankAccountName || '—'}
              </Descriptions.Item>
              <Descriptions.Item label="收款账号">
                {storeAccount?.bankAccountNo || '—'}
              </Descriptions.Item>
              <Descriptions.Item label="开户行">{storeAccount?.bankBranch || '—'}</Descriptions.Item>
            </Descriptions>

            <Typography.Title level={5} style={{ marginTop: 24 }}>
              关联结算明细
            </Typography.Title>
            <Table
              size="small"
              rowKey={(r) => String((r as { id?: string }).id)}
              pagination={false}
              dataSource={detailItems}
              columns={[
                {
                  title: '核销单号',
                  render: (_, r) => {
                    const payout = (r as { storePayout?: { redeemRecord?: { redeemNo?: string } } })
                      .storePayout;
                    return payout?.redeemRecord?.redeemNo || '—';
                  },
                },
                {
                  title: '结算额',
                  render: (_, r) => {
                    const payout = (r as { storePayout?: { payoutAmount?: number } }).storePayout;
                    return `¥${Number(payout?.payoutAmount ?? 0).toFixed(2)}`;
                  },
                },
              ]}
            />
          </>
        ) : null}
      </Drawer>
    </div>
  );
}
