import React, { useEffect, useState, useMemo, useCallback } from 'react';
import {
  Table,
  Modal,
  Form,
  DatePicker,
  Space,
  message,
  Tag,
  Descriptions,
  Popconfirm,
  Input,
  Select,
  Tooltip,
  Spin,
  Empty,
} from 'antd';
import {
  FileTextOutlined,
  DeleteOutlined,
  DownloadOutlined,
  FilePdfOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import { downloadBlob } from '../../utils/download';

const { RangePicker } = DatePicker;

const statusMap: Record<string, { text: string; color: string }> = {
  draft: { text: '草稿', color: 'default' },
  confirmed: { text: '已确认', color: 'blue' },
  paid: { text: '已支付', color: 'green' },
};

const typeMap: Record<string, string> = {
  water: '水费',
  electricity: '电费',
  cleaning: '保洁费',
  damage: '损坏赔偿',
  penalty: '罚款',
  other: '其他',
};

const BillsPage: React.FC = () => {
  const [bills, setBills] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [generateModal, setGenerateModal] = useState(false);
  const [detailModal, setDetailModal] = useState<any>(null);
  const [selectedRows, setSelectedRows] = useState<number[]>([]);
  const [searchText, setSearchText] = useState('');
  const [filterStatus, setFilterStatus] = useState<string | undefined>(undefined);
  const [filterExpenseType, setFilterExpenseType] = useState<string | undefined>(undefined);
  const [generateForm] = Form.useForm();
  const [saving, setSaving] = useState(false);
  const [detailLoading, setDetailLoading] = useState(false);
  const [batchLoading, setBatchLoading] = useState(false);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, string | undefined> = {};
      if (filterStatus) params.status = filterStatus;
      if (filterExpenseType) params.expenseType = filterExpenseType;
      const res = await api.get('/bills', { params }) as unknown[];
      setBills(res);
    } catch (e: any) {
      message.error(e?.message || '加载失败，请稍后重试');
    }
    setLoading(false);
  }, [filterStatus, filterExpenseType]);

  useEffect(() => {
    fetchData();
  }, [fetchData]);

  const filteredBills = useMemo(() => {
    return bills.filter((b: any) => {
      if (searchText) {
        const s = searchText.toLowerCase();
        const matchName = b.student?.name?.toLowerCase().includes(s);
        const matchPeriod = `${b.periodStart} ~ ${b.periodEnd}`.includes(s);
        if (!matchName && !matchPeriod) return false;
      }
      if (filterStatus && b.status !== filterStatus) return false;
      return true;
    });
  }, [bills, searchText, filterStatus]);

  const handleGenerate = async () => {
    setSaving(true);
    const values = await generateForm.validateFields();
    try {
      const res: any = await api.post('/bills/generate', {
        periodStart: values.period[0].format('YYYY-MM-DD'),
        periodEnd: values.period[1].format('YYYY-MM-DD'),
      });
      message.success(res.message || '生成成功');
      setGenerateModal(false);
      generateForm.resetFields();
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '生成失败');
    } finally {
      setSaving(false);
    }
  };

  const showDetail = async (id: number) => {
    setDetailLoading(true);
    try {
      const res = await api.get(`/bills/${id}`);
      setDetailModal(res);
    } catch (e: any) {
      message.error(e?.message || '加载失败，请稍后重试');
    } finally {
      setDetailLoading(false);
    }
  };

  const updateStatus = async (id: number, status: string) => {
    try {
      await api.put(`/bills/${id}/status`, { status });
      message.success('状态更新成功');
      fetchData();
      if (detailModal?.id === id) {
        setDetailModal({ ...detailModal, status });
      }
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    }
  };

  const batchUpdateStatus = async (status: string) => {
    if (selectedRows.length === 0) return message.warning('请先选择账单');
    if (batchLoading) return;
    setBatchLoading(true);
    try {
      await api.put('/bills/batch/status', { ids: selectedRows, status });
      message.success(`已批量更新 ${selectedRows.length} 条账单`);
      setSelectedRows([]);
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setBatchLoading(false);
    }
  };

  const handleDelete = async (id: number) => {
    try {
      await api.delete(`/bills/${id}`);
      message.success('账单已删除');
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '删除失败');
    }
  };

  const batchDelete = async () => {
    if (selectedRows.length === 0) return message.warning('请先选择账单');
    if (batchLoading) return;
    setBatchLoading(true);
    try {
      await api.post('/bills/batch/delete', { ids: selectedRows });
      message.success(`已删除 ${selectedRows.length} 条账单`);
      setSelectedRows([]);
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setBatchLoading(false);
    }
  };

  const handleExportExcel = () => {
    downloadBlob('/bills/export/excel', `账单导出_${dayjs().format('YYYYMMDD_HHmmss')}.xlsx`).then(
      () => message.success('Excel 导出成功'),
      () => message.error('导出失败'),
    );
  };

  const handleExportPdf = (billId: number) => {
    downloadBlob(`/bills/export/pdf/${billId}`, `账单_${billId}.pdf`).catch(() =>
      message.error('导出失败'),
    );
  };

  const columns = useMemo(() => [
    { title: '学生', width: 120, render: (_: any, r: any) => r.student?.name || '-' },
    { title: '账单周期', width: 200, render: (_: any, r: any) => `${r.periodStart} ~ ${r.periodEnd}` },
    {
      title: '分摊费用',
      dataIndex: 'sharedAmount',
      width: 120,
      align: 'right' as const,
      render: (v: number) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '个人费用',
      dataIndex: 'personalAmount',
      width: 120,
      align: 'right' as const,
      render: (v: number) => `¥${Number(v).toFixed(2)}`,
    },
    {
      title: '总计',
      dataIndex: 'totalAmount',
      width: 100,
      align: 'right' as const,
      render: (v: number) => <strong>¥{Number(v).toFixed(2)}</strong>,
    },
    {
      title: '可用押金',
      dataIndex: 'availableDeposit',
      width: 120,
      render: (v: number) =>
        v > 0 ? (
          <span style={{ color: '#52c41a' }}>¥{Number(v).toFixed(2)}</span>
        ) : (
          <span style={{ color: '#999' }}>-</span>
        ),
    },
    {
      title: '抵扣后应付',
      dataIndex: 'amountAfterDeposit',
      width: 130,
      render: (v: number, r: any) => {
        const has = Number(r.availableDeposit || 0) > 0;
        if (!has) return <span style={{ color: '#999' }}>-</span>;
        const after = Number(v ?? r.totalAmount).toFixed(2);
        const applied = Number(r.depositApplied || 0).toFixed(2);
        return (
          <Tooltip title={`已抵扣押金 ¥${applied}`}>
            <strong style={{ color: '#fa541c' }}>¥{after}</strong>
          </Tooltip>
        );
      },
    },
    {
      title: '状态',
      dataIndex: 'status',
      width: 90,
      render: (s: string) => <Tag color={statusMap[s]?.color}>{statusMap[s]?.text}</Tag>,
    },
    {
      title: '生成时间',
      dataIndex: 'generatedAt',
      width: 160,
      render: (v: string) => dayjs(v).format('YYYY-MM-DD HH:mm'),
    },
    {
      title: '操作',
      width: 320,
      render: (_: any, record: any) => (
        <Space>
          <PermissionButton
            permission="bill:view"
            size="small"
            type="link"
            onClick={() => showDetail(record.id)}
          >
            详情
          </PermissionButton>
          {record.status === 'draft' && (
            <PermissionButton
              permission="bill:confirm"
              size="small"
              onClick={() => updateStatus(record.id, 'confirmed')}
            >
              确认
            </PermissionButton>
          )}
          {record.status === 'confirmed' && (
            <PermissionButton
              permission="bill:confirm"
              size="small"
              type="primary"
              onClick={() => updateStatus(record.id, 'paid')}
            >
              标记已付
            </PermissionButton>
          )}
          <PermissionButton
            permission="bill:export-pdf"
            size="small"
            icon={<FilePdfOutlined />}
            onClick={() => handleExportPdf(record.id)}
          >
            PDF
          </PermissionButton>
          <Popconfirm
            title="确定删除此账单？"
            onConfirm={() => handleDelete(record.id)}
            okText="删除"
            cancelText="取消"
          >
            <PermissionButton permission="bill:delete" size="small" danger icon={<DeleteOutlined />}>
              删除
            </PermissionButton>
          </Popconfirm>
        </Space>
      ),
    },
  ], [showDetail, updateStatus, handleDelete, handleExportPdf]);

  return (
    <div>
      <div
        style={{
          marginBottom: 16,
          display: 'flex',
          justifyContent: 'space-between',
          flexWrap: 'wrap',
          gap: 8,
        }}
      >
        <Space wrap>
          <Input.Search
            placeholder="搜索学生姓名或账单周期"
            allowClear
            style={{ width: 220 }}
            onSearch={(v) => setSearchText(v)}
            onChange={(e) => {
              if (!e.target.value) setSearchText('');
            }}
          />
          <Select
            placeholder="状态筛选"
            allowClear
            style={{ width: 120 }}
            value={filterStatus}
            onChange={(v) => setFilterStatus(v)}
            options={[
              { value: 'draft', label: '草稿' },
              { value: 'confirmed', label: '已确认' },
              { value: 'paid', label: '已支付' },
            ]}
          />
          <Select placeholder="费用类型" allowClear style={{ width: 120 }} value={filterExpenseType} onChange={setFilterExpenseType}
            options={[{value:'water',label:'水费'},{value:'electricity',label:'电费'},{value:'cleaning',label:'保洁费'},{value:'rent',label:'租金'},{value:'other',label:'其他'}]} />
          <PermissionButton
            permission="bill:confirm"
            onClick={() => batchUpdateStatus('confirmed')}
            disabled={selectedRows.length === 0}
          >
            批量确认
          </PermissionButton>
          <PermissionButton
            permission="bill:confirm"
            type="primary"
            onClick={() => batchUpdateStatus('paid')}
            disabled={selectedRows.length === 0}
          >
            批量标记已付
          </PermissionButton>
          <Popconfirm
            title={`确定删除选中的 ${selectedRows.length} 条账单？`}
            onConfirm={batchDelete}
            okText="删除"
            cancelText="取消"
            disabled={selectedRows.length === 0}
          >
            <PermissionButton
              permission="bill:delete"
              danger
              disabled={selectedRows.length === 0}
              icon={<DeleteOutlined />}
            >
              批量删除
            </PermissionButton>
          </Popconfirm>
        </Space>
        <Space>
          <PermissionButton
            permission="bill:generate"
            type="primary"
            icon={<FileTextOutlined />}
            onClick={() => {
              generateForm.resetFields();
              setGenerateModal(true);
            }}
          >
            生成账单
          </PermissionButton>
          <PermissionButton
            permission="bill:export-excel"
            icon={<DownloadOutlined />}
            onClick={handleExportExcel}
          >
            导出Excel
          </PermissionButton>
        </Space>
      </div>
      <Table
        scroll={{ x: 1400 }}
        columns={columns}
        dataSource={filteredBills}
        rowKey="id"
        loading={loading}
        pagination={{ pageSize: 15, showTotal: (total) => `共 ${total} 条` }}
        locale={{ emptyText: <Empty description="暂无数据" /> }}
        rowSelection={{
          selectedRowKeys: selectedRows,
          onChange: (keys) => setSelectedRows(keys as number[]),
        }}
      />

      <Modal
        title="生成账单"
        open={generateModal}
        onOk={handleGenerate}
        onCancel={() => setGenerateModal(false)}
        okText="生成"
        confirmLoading={saving}
      >
        <Form form={generateForm} layout="vertical">
          <Form.Item
            name="period"
            label="账单周期"
            rules={[{ required: true, message: '请选择账单周期' }]}
            extra="选择费用对应的时间段，系统将自动计算每个学生的分摊费用"
          >
            <RangePicker
              style={{ width: '100%' }}
              placeholder={['开始日期', '结束日期']}
              format="YYYY-MM-DD"
            />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title="账单详情"
        open={!!detailModal}
        onCancel={() => setDetailModal(null)}
        footer={null}
        width={800}
      >
        {detailModal && (
          <Spin spinning={detailLoading}>
            <Descriptions bordered size="small" column={2} style={{ marginBottom: 16 }}>
              <Descriptions.Item label="学生">{detailModal.student?.name}</Descriptions.Item>
              <Descriptions.Item label="状态">
                <Tag color={statusMap[detailModal.status]?.color}>
                  {statusMap[detailModal.status]?.text}
                </Tag>
              </Descriptions.Item>
              <Descriptions.Item label="账单周期">
                {detailModal.periodStart} ~ {detailModal.periodEnd}
              </Descriptions.Item>
              <Descriptions.Item label="生成时间">
                {dayjs(detailModal.generatedAt).format('YYYY-MM-DD HH:mm')}
              </Descriptions.Item>
              <Descriptions.Item label="分摊费用">
                ¥{Number(detailModal.sharedAmount).toFixed(2)}
              </Descriptions.Item>
              <Descriptions.Item label="个人费用">
                ¥{Number(detailModal.personalAmount).toFixed(2)}
              </Descriptions.Item>
              <Descriptions.Item label="合计" span={2}>
                <strong style={{ fontSize: 18, color: '#007AFF' }}>
                  ¥{Number(detailModal.totalAmount).toFixed(2)}
                </strong>
              </Descriptions.Item>
            </Descriptions>
            {Number(detailModal.availableDeposit || 0) > 0 && (
              <div
                style={{
                  marginBottom: 16,
                  padding: 12,
                  background: '#f6ffed',
                  border: '1px solid #b7eb8f',
                  borderRadius: 8,
                }}
              >
                <div style={{ fontSize: 13, color: '#666', marginBottom: 6 }}>
                  押金联动（不影响实际押金状态，仅作收款参考）
                </div>
                <Space size={24} wrap>
                  <span>
                    当前可用押金：
                    <strong style={{ color: '#52c41a' }}>
                      ¥{Number(detailModal.availableDeposit).toFixed(2)}
                    </strong>
                  </span>
                  <span>
                    本账单可抵扣：
                    <strong style={{ color: '#fa8c16' }}>
                      -¥{Number(detailModal.depositApplied || 0).toFixed(2)}
                    </strong>
                  </span>
                  <span>
                    抵扣后实付：
                    <strong style={{ color: '#fa541c', fontSize: 16 }}>
                      ¥
                      {Number(detailModal.amountAfterDeposit ?? detailModal.totalAmount).toFixed(2)}
                    </strong>
                  </span>
                </Space>
              </div>
            )}
            <h4>费用明细</h4>
            <Table
              scroll={{ x: 700 }}
              dataSource={detailModal.items || []}
              rowKey="id"
              pagination={false}
              size="small"
              columns={[
                { title: '类型', dataIndex: 'expenseType', render: (v: string) => typeMap[v] || v },
                { title: '说明', dataIndex: 'description' },
                {
                  title: '计费天数',
                  dataIndex: 'days',
                  render: (v: number) => (v > 0 ? `${v}天` : '-'),
                },
                {
                  title: '宿舍总人天',
                  dataIndex: 'totalRoomDays',
                  render: (v: number) => (v > 0 ? `${v}天` : '-'),
                },
                {
                  title: '宿舍总费用',
                  dataIndex: 'roomTotalAmount',
                  render: (v: number) => `¥${Number(v).toFixed(2)}`,
                },
                {
                  title: '应分摊',
                  dataIndex: 'studentAmount',
                  render: (v: number) => <strong>¥{Number(v).toFixed(2)}</strong>,
                },
              ]}
            />
          </Spin>
        )}
      </Modal>
    </div>
  );
};

export default BillsPage;
