import React, { useEffect, useState, useMemo, useCallback } from 'react';
import {
  Table,
  Button,
  Modal,
  Form,
  Select,
  DatePicker,
  InputNumber,
  Input,
  Space,
  Tag,
  Tabs,
  Popconfirm,
  Upload,
  Empty,
} from 'antd';
import {
  PlusOutlined,
  DeleteOutlined,
  EditOutlined,
  UploadOutlined,
  DownloadOutlined,
  ExportOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import { downloadBlob } from '../../utils/download';
import { message } from '../../ui/app-message';

const { RangePicker } = DatePicker;



const ExpensesPage: React.FC = () => {
  const [roomExpenses, setRoomExpenses] = useState<any[]>([]);
  const [personalExpenses, setPersonalExpenses] = useState<any[]>([]);
  const [rooms, setRooms] = useState<any[]>([]);
  const [students, setStudents] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [roomModal, setRoomModal] = useState(false);
  const [personalModal, setPersonalModal] = useState(false);
  const [editingRoom, setEditingRoom] = useState<any>(null);
  const [editingPersonal, setEditingPersonal] = useState<any>(null);
  const [roomForm] = Form.useForm();
  const [personalForm] = Form.useForm();
  const [roomSearch, setRoomSearch] = useState('');
  const [roomTypeFilter, setRoomTypeFilter] = useState<string | undefined>(undefined);
  const [personalSearch, setPersonalSearch] = useState('');
  const [personalTypeFilter, setPersonalTypeFilter] = useState<string | undefined>(undefined);
  const [selectedRoomKeys, setSelectedRoomKeys] = useState<number[]>([]);
  const [selectedPersonalKeys, setSelectedPersonalKeys] = useState<number[]>([]);
  const [saving, setSaving] = useState(false);
  const [batchLoading, setBatchLoading] = useState(false);

  // Dynamic expense type options from API
  const [typeOptions, setTypeOptions] = useState<{ value: string; label: string }[]>([]);
  const [personalTypeOptions, setPersonalTypeOptions] = useState<{ value: string; label: string }[]>([]);
  const [typeMap, setTypeMap] = useState<Record<string, string>>({});

  useEffect(() => {
    api.get<Array<{ code: string; name: string; category: string }>>('/expense-types').then((types) => {
      const roomTypes: { value: string; label: string }[] = [];
      const personalTypes: { value: string; label: string }[] = [];
      const map: Record<string, string> = {};
      for (const t of types) {
        map[t.code] = t.name;
        if (t.category === 'room' || t.category === 'both') {
          roomTypes.push({ value: t.code, label: t.name });
        }
        if (t.category === 'personal' || t.category === 'both') {
          personalTypes.push({ value: t.code, label: t.name });
        }
      }
      setTypeOptions(roomTypes);
      setPersonalTypeOptions(personalTypes);
      setTypeMap(map);
    }).catch(() => {});
  }, []);

  const handleBatchDeleteRoom = async () => {
    if (batchLoading) return;
    setBatchLoading(true);
    try {
      const res: any = await api.post('/expenses/room/batch-delete', { ids: selectedRoomKeys });
      message.success(res?.message || `已删除 ${selectedRoomKeys.length} 条`);
      setSelectedRoomKeys([]);
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '批量删除失败');
    } finally {
      setBatchLoading(false);
    }
  };

  const handleBatchDeletePersonal = async () => {
    if (batchLoading) return;
    setBatchLoading(true);
    try {
      const res: any = await api.post('/expenses/personal/batch-delete', {
        ids: selectedPersonalKeys,
      });
      message.success(res?.message || `已删除 ${selectedPersonalKeys.length} 条`);
      setSelectedPersonalKeys([]);
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '批量删除失败');
    } finally {
      setBatchLoading(false);
    }
  };

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const [re, pe, rm, st]: any[] = await Promise.all([
        api.get('/expenses/room'),
        api.get('/expenses/personal'),
        api.get('/rooms'),
        api.get('/students'),
      ]);
      setRoomExpenses(re);
      setPersonalExpenses(pe);
      setRooms(rm);
      setStudents(st);
    } catch (e: any) {
      message.error(e?.message || '加载失败，请稍后重试');
    }
    setLoading(false);
  }, []);

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

  const filteredRoomExpenses = useMemo(() => {
    return roomExpenses.filter((r: any) => {
      if (roomSearch) {
        const s = roomSearch.toLowerCase();
        if (!r.room?.roomNumber?.toLowerCase().includes(s)) return false;
      }
      if (roomTypeFilter && r.expenseType !== roomTypeFilter) return false;
      return true;
    });
  }, [roomExpenses, roomSearch, roomTypeFilter]);

  const filteredPersonalExpenses = useMemo(() => {
    return personalExpenses.filter((p: any) => {
      if (personalSearch) {
        const s = personalSearch.toLowerCase();
        if (!p.student?.name?.toLowerCase().includes(s)) return false;
      }
      if (personalTypeFilter && p.expenseType !== personalTypeFilter) return false;
      return true;
    });
  }, [personalExpenses, personalSearch, personalTypeFilter]);

  const handleRoomExpense = async () => {
    setSaving(true);
    const values = await roomForm.validateFields();
    const payload = {
      roomId: values.roomId,
      expenseType: values.expenseType,
      amount: values.amount,
      periodStart: values.period[0].format('YYYY-MM-DD'),
      periodEnd: values.period[1].format('YYYY-MM-DD'),
      description: values.description,
    };
    try {
      if (editingRoom) {
        await api.put(`/expenses/room/${editingRoom.id}`, payload);
        message.success('更新成功');
      } else {
        await api.post('/expenses/room', payload);
        message.success('录入成功');
      }
      setRoomModal(false);
      setEditingRoom(null);
      roomForm.resetFields();
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setSaving(false);
    }
  };

  const handlePersonalExpense = async () => {
    setSaving(true);
    const values = await personalForm.validateFields();
    const payload = {
      studentId: values.studentId,
      roomId: values.roomId,
      expenseType: values.expenseType,
      amount: values.amount,
      expenseDate: values.expenseDate.format('YYYY-MM-DD'),
      description: values.description,
    };
    try {
      if (editingPersonal) {
        await api.put(`/expenses/personal/${editingPersonal.id}`, payload);
        message.success('更新成功');
      } else {
        await api.post('/expenses/personal', payload);
        message.success('录入成功');
      }
      setPersonalModal(false);
      setEditingPersonal(null);
      personalForm.resetFields();
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setSaving(false);
    }
  };

  const roomColumns = useMemo(() => [
    { title: '宿舍', width: 120, render: (_: any, r: any) => r.room?.roomNumber || '-' },
    {
      title: '费用类型', width: 100,
      dataIndex: 'expenseType',
      render: (v: string) => <Tag>{typeMap[v] || v}</Tag>,
    },
    { title: '金额', dataIndex: 'amount', width: 100, render: (v: number) => `¥${Number(v).toFixed(2)}` },
    { title: '账单周期', width: 200, render: (_: any, r: any) => `${r.periodStart} ~ ${r.periodEnd}` },
    { title: '说明', dataIndex: 'description', width: 150 },
    {
      title: '录入时间', width: 160,
      dataIndex: 'createdAt',
      render: (v: string) => dayjs(v).format('YYYY-MM-DD HH:mm'),
    },
    {
      title: '操作',
      width: 120,
      render: (_: any, record: any) => (
        <Space>
          <PermissionButton
            permission="expense:edit"
            size="small"
            icon={<EditOutlined />}
            onClick={() => {
              setEditingRoom(record);
              roomForm.setFieldsValue({
                roomId: record.roomId,
                expenseType: record.expenseType,
                amount: Number(record.amount),
                period: [dayjs(record.periodStart), dayjs(record.periodEnd)],
                description: record.description,
              });
              setRoomModal(true);
            }}
          >
            编辑
          </PermissionButton>
          <Popconfirm
            title="确定删除？"
            onConfirm={async () => {
              await api.delete(`/expenses/room/${record.id}`);
              message.success('删除成功');
              fetchData();
            }}
          >
            <PermissionButton
              permission="expense:delete"
              size="small"
              danger
              icon={<DeleteOutlined />}
            >
              删除
            </PermissionButton>
          </Popconfirm>
        </Space>
      ),
    },
  ], [setEditingRoom, roomForm, setRoomModal, fetchData, typeMap]);

  const personalColumns = useMemo(() => [
    { title: '学生', width: 120, render: (_: any, r: any) => r.student?.name || '-' },
    {
      title: '费用类型', width: 100,
      dataIndex: 'expenseType',
      render: (v: string) => <Tag color="orange">{typeMap[v] || v}</Tag>,
    },
    { title: '金额', dataIndex: 'amount', render: (v: number) => `¥${Number(v).toFixed(2)}` },
    { title: '日期', dataIndex: 'expenseDate', width: 110 },
    { title: '说明', dataIndex: 'description', width: 150 },
    {
      title: '操作',
      width: 120,
      render: (_: any, record: any) => (
        <Space>
          <PermissionButton
            permission="expense:edit"
            size="small"
            icon={<EditOutlined />}
            onClick={() => {
              setEditingPersonal(record);
              personalForm.setFieldsValue({
                studentId: record.studentId,
                roomId: record.roomId,
                expenseType: record.expenseType,
                amount: Number(record.amount),
                expenseDate: dayjs(record.expenseDate),
                description: record.description,
              });
              setPersonalModal(true);
            }}
          >
            编辑
          </PermissionButton>
          <Popconfirm
            title="确定删除？"
            onConfirm={async () => {
              await api.delete(`/expenses/personal/${record.id}`);
              message.success('删除成功');
              fetchData();
            }}
          >
            <PermissionButton
              permission="expense:delete"
              size="small"
              danger
              icon={<DeleteOutlined />}
            >
              删除
            </PermissionButton>
          </Popconfirm>
        </Space>
      ),
    },
  ], [setEditingPersonal, personalForm, setPersonalModal, fetchData, typeMap]);

  return (
    <div>
      <Tabs
        items={[
          {
            key: 'room',
            label: '宿舍费用',
            children: (
              <>
                <div
                  style={{
                    marginBottom: 16,
                    display: 'flex',
                    justifyContent: 'space-between',
                    flexWrap: 'wrap',
                    gap: 8,
                  }}
                >
                  <Space wrap>
                    <Input.Search
                      placeholder="搜索宿舍号"
                      allowClear
                      style={{ width: 160 }}
                      onSearch={(v) => setRoomSearch(v)}
                      onChange={(e) => {
                        if (!e.target.value) setRoomSearch('');
                      }}
                    />
                    <Select
                      placeholder="费用类型"
                      allowClear
                      style={{ width: 120 }}
                      value={roomTypeFilter}
                      onChange={(v) => setRoomTypeFilter(v)}
                      options={typeOptions}
                    />
                    <Upload
                      accept=".xlsx,.xls"
                      showUploadList={false}
                      customRequest={async ({ file, onSuccess, onError }: any) => {
                        const formData = new FormData();
                        formData.append('file', file);
                        try {
                          const res: any = await api.post('/expenses/utility/import', formData);
                          if (res.errors?.length > 0) {
                            Modal.warning({
                              title: res.message,
                              content: res.errors.join('\n'),
                              width: 500,
                            });
                          } else {
                            message.success(res.message);
                          }
                          onSuccess?.(res);
                          fetchData();
                        } catch (e: any) {
                          message.error(e?.message || '导入失败');
                          onError?.(e);
                        }
                      }}
                    >
                      <Button icon={<UploadOutlined />}>导入水电费Excel</Button>
                    </Upload>
                    <PermissionButton
                      permission="expense:view"
                      icon={<DownloadOutlined />}
                      onClick={() => {
                        downloadBlob('/expenses/utility/template', '水电费导入模板.xlsx').catch(() =>
                          message.error('下载失败'),
                        );
                      }}
                    >
                      下载水电费模板
                    </PermissionButton>
                  </Space>
                  <Space>
                    <Popconfirm
                      title={`确定删除选中的 ${selectedRoomKeys.length} 条费用？`}
                      onConfirm={handleBatchDeleteRoom}
                      okText="删除"
                      cancelText="取消"
                      disabled={selectedRoomKeys.length === 0}
                    >
                      <PermissionButton
                        permission="expense:delete"
                        danger
                        icon={<DeleteOutlined />}
                        disabled={selectedRoomKeys.length === 0}
                      >
                        批量删除
                      </PermissionButton>
                    </Popconfirm>
                    <PermissionButton
                      permission="expense:create"
                      type="primary"
                      icon={<PlusOutlined />}
                      onClick={() => {
                        setEditingRoom(null);
                        roomForm.resetFields();
                        setRoomModal(true);
                      }}
                    >
                      录入宿舍费用
                    </PermissionButton>
                  </Space>
                </div>
                <Table
                  columns={roomColumns}
                  dataSource={filteredRoomExpenses}
                  rowKey="id"
                  loading={loading}
                  scroll={{ x: 1200 }}
                  pagination={{ pageSize: 15, showTotal: (total) => `共 ${total} 条` }}
                  locale={{ emptyText: <Empty description="暂无数据" /> }}
                  rowSelection={{
                    selectedRowKeys: selectedRoomKeys,
                    onChange: (keys) => setSelectedRoomKeys(keys as number[]),
                  }}
                />
              </>
            ),
          },
          {
            key: 'personal',
            label: '个人附加费',
            children: (
              <>
                <div
                  style={{
                    marginBottom: 16,
                    display: 'flex',
                    justifyContent: 'space-between',
                    flexWrap: 'wrap',
                    gap: 8,
                  }}
                >
                  <Space wrap>
                    <Input.Search
                      placeholder="搜索学生姓名"
                      allowClear
                      style={{ width: 160 }}
                      onSearch={(v) => setPersonalSearch(v)}
                      onChange={(e) => {
                        if (!e.target.value) setPersonalSearch('');
                      }}
                    />
                    <Select
                      placeholder="费用类型"
                      allowClear
                      style={{ width: 120 }}
                      value={personalTypeFilter}
                      onChange={(v) => setPersonalTypeFilter(v)}
                      options={personalTypeOptions}
                    />
                    <Upload
                      accept=".xlsx,.xls"
                      showUploadList={false}
                      customRequest={async ({ file, onSuccess, onError }: any) => {
                        try {
                          const formData = new FormData();
                          formData.append('file', file);
                          const res: any = await api.post('/expenses/personal/import', formData);
                          message.success(res.message || '导入完成');
                          if (res.errors?.length)
                            res.errors.forEach((e: string) => message.warning(e));
                          fetchData();
                          onSuccess?.(res);
                        } catch (e: any) {
                          message.error(e?.message || '导入失败');
                          onError?.(e);
                        }
                      }}
                    >
                      <Button icon={<UploadOutlined />}>导入个人附加费</Button>
                    </Upload>
                    <PermissionButton
                      permission="expense:view"
                      icon={<DownloadOutlined />}
                      onClick={() => {
                        downloadBlob('/expenses/personal/template', '个人附加费导入模板.xlsx').catch(
                          () => message.error('下载失败'),
                        );
                      }}
                    >
                      下载模板
                    </PermissionButton>
                    <PermissionButton
                      permission="expense:view"
                      icon={<ExportOutlined />}
                      onClick={() => {
                        downloadBlob('/expenses/personal/export', '个人附加费导出.xlsx').catch(() =>
                          message.error('导出失败'),
                        );
                      }}
                    >
                      导出
                    </PermissionButton>
                  </Space>
                  <Space>
                    <Popconfirm
                      title={`确定删除选中的 ${selectedPersonalKeys.length} 条个人费用？`}
                      onConfirm={handleBatchDeletePersonal}
                      okText="删除"
                      cancelText="取消"
                      disabled={selectedPersonalKeys.length === 0}
                    >
                      <PermissionButton
                        permission="expense:delete"
                        danger
                        icon={<DeleteOutlined />}
                        disabled={selectedPersonalKeys.length === 0}
                      >
                        批量删除
                      </PermissionButton>
                    </Popconfirm>
                    <PermissionButton
                      permission="expense:create"
                      type="primary"
                      icon={<PlusOutlined />}
                      onClick={() => {
                        setEditingPersonal(null);
                        personalForm.resetFields();
                        setPersonalModal(true);
                      }}
                    >
                      录入个人费用
                    </PermissionButton>
                  </Space>
                </div>
                <Table
                  columns={personalColumns}
                  dataSource={filteredPersonalExpenses}
                  rowKey="id"
                  loading={loading}
                  scroll={{ x: 1200 }}
                  pagination={{ pageSize: 15, showTotal: (total) => `共 ${total} 条` }}
                  locale={{ emptyText: <Empty description="暂无数据" /> }}
                  rowSelection={{
                    selectedRowKeys: selectedPersonalKeys,
                    onChange: (keys) => setSelectedPersonalKeys(keys as number[]),
                  }}
                />
              </>
            ),
          },
        ]}
      />

      <Modal
        title={editingRoom ? '编辑宿舍费用' : '录入宿舍费用'}
        open={roomModal}
        onOk={handleRoomExpense}
        onCancel={() => {
          setRoomModal(false);
          setEditingRoom(null);
        }}
        okText={editingRoom ? '保存' : '确认录入'}
        confirmLoading={saving}
      >
        <Form form={roomForm} layout="vertical">
          <Form.Item name="roomId" label="宿舍" rules={[{ required: true }]}>
            <Select
              showSearch
              optionFilterProp="label"
              options={rooms.map((r: any) => ({
                value: r.id,
                label: `${r.roomNumber} (${r.building || ''})`,
              }))}
            />
          </Form.Item>
          <Form.Item name="expenseType" label="费用类型" rules={[{ required: true }]}>
            <Select options={typeOptions} />
          </Form.Item>
          <Form.Item name="amount" label="金额（元）" rules={[{ required: true }]}>
            <InputNumber min={0} precision={2} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="period" label="账单周期" rules={[{ required: true }]}>
            <RangePicker
              style={{ width: '100%' }}
              placeholder={['开始日期', '结束日期']}
              format="YYYY-MM-DD"
            />
          </Form.Item>
          <Form.Item name="description" label="说明">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={editingPersonal ? '编辑个人费用' : '录入个人附加费'}
        open={personalModal}
        onOk={handlePersonalExpense}
        onCancel={() => {
          setPersonalModal(false);
          setEditingPersonal(null);
        }}
        okText={editingPersonal ? '保存' : '确认录入'}
        confirmLoading={saving}
      >
        <Form form={personalForm} layout="vertical">
          <Form.Item name="studentId" label="学生" rules={[{ required: true }]}>
            <Select
              showSearch
              optionFilterProp="label"
              options={students.map((s: any) => ({ value: s.id, label: s.name }))}
            />
          </Form.Item>
          <Form.Item name="roomId" label="关联宿舍">
            <Select
              allowClear
              showSearch
              optionFilterProp="label"
              options={rooms.map((r: any) => ({ value: r.id, label: r.roomNumber }))}
            />
          </Form.Item>
          <Form.Item name="expenseType" label="费用类型" rules={[{ required: true }]}>
            <Select options={personalTypeOptions} />
          </Form.Item>
          <Form.Item name="amount" label="金额（元）" rules={[{ required: true }]}>
            <InputNumber min={0} precision={2} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="expenseDate" label="费用日期" rules={[{ required: true }]}>
            <DatePicker style={{ width: '100%' }} placeholder="选择日期" format="YYYY-MM-DD" />
          </Form.Item>
          <Form.Item name="description" label="说明">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default ExpensesPage;
