import React, { useCallback, useEffect, useMemo, useState } from 'react';
import {
  Table,
  Modal,
  Form,
  Select,
  DatePicker,
  InputNumber,
  Input,
  Space,
  Tag,
  Popconfirm,
  Card,
  Empty,
} from 'antd';
import { PlusOutlined, InboxOutlined, DollarOutlined, TeamOutlined } from '@ant-design/icons';
import dayjs from 'dayjs';
import api from '../../api';
import PermissionButton from '../../components/PermissionButton';
import EditableCell from '../../components/EditableCell';
import { message } from '../../ui/app-message';
import { buildDepositStudentOptions, type DepositStudentLookup } from './deposit-student-option';

const statusMap: Record<string, { text: string; color: string }> = {
  paid: { text: '有余额', color: 'green' },
  refunded: { text: '已全退', color: 'blue' },
  depleted: { text: '已扣完', color: 'red' },
};

const installmentStatusMap: Record<string, { text: string; color: string }> = {
  pending: { text: '待缴', color: 'orange' },
  paid: { text: '已缴', color: 'green' },
};

const roomTypeOptions = [
  { value: '单人间', label: '单人间' },
  { value: '四人间', label: '四人间' },
];

const suggestedDepositByRoomType: Record<string, number> = {
  单人间: 200,
  四人间: 100,
};

interface DepositRecord {
  id: number;
  studentId: number;
  amount: number;
  status: string;
  paidDate: string;
  refundDate?: string | null;
  notes?: string | null;
  installments?: Array<{
    id: number;
    amount: number;
    dueDate: string;
    paidDate?: string | null;
    status: string;
  }>;
  student?: DepositStudentLookup;
}

interface EligibleStudent {
  studentId: number;
  studentName: string;
  studentNo?: string | null;
  roomId: number;
  roomNumber: string;
  building?: string | null;
  roomType?: string | null;
  capacity: number;
  depositAmount: number;
}

const isFormValidationError = (error: unknown) =>
  typeof error === 'object' &&
  error !== null &&
  Array.isArray((error as { errorFields?: unknown }).errorFields);

const DepositsPage: React.FC = () => {
  const [data, setData] = useState<DepositRecord[]>([]);
  const [students, setStudents] = useState<DepositStudentLookup[]>([]);
  const [eligibleStudents, setEligibleStudents] = useState<EligibleStudent[]>([]);
  const [selectedEligibleStudentIds, setSelectedEligibleStudentIds] = useState<number[]>([]);
  const [loading, setLoading] = useState(false);
  const [eligibleLoading, setEligibleLoading] = useState(false);
  const [createModal, setCreateModal] = useState(false);
  const [batchModal, setBatchModal] = useState(false);
  const [refundModal, setRefundModal] = useState<DepositRecord | null>(null);
  const [detailModal, setDetailModal] = useState<DepositRecord | null>(null);
  const [installmentModal, setInstallmentModal] = useState<number | null>(null);
  const [createForm] = Form.useForm();
  const [batchForm] = Form.useForm();
  const [refundForm] = Form.useForm();
  const [installmentForm] = Form.useForm();
  const [searchText, setSearchText] = useState('');
  const [filterStatus, setFilterStatus] = useState<string | undefined>(undefined);
  const [filterRoomType, setFilterRoomType] = useState<string | undefined>(undefined);
  const [batchRoomType, setBatchRoomType] = useState<string>('四人间');
  const [saving, setSaving] = useState(false);

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const [d, s] = await Promise.all([
        api.get<DepositRecord[]>('/deposits'),
        api.get<DepositStudentLookup[]>('/deposits/student-lookups'),
      ]);
      setData(d);
      setStudents(s);
    } catch (e: any) {
      message.error(e?.message || '加载失败，请稍后重试');
    } finally {
      setLoading(false);
    }
  }, []);

  const fetchEligibleStudents = useCallback(async (roomType?: string) => {
    setEligibleLoading(true);
    try {
      const params = roomType ? `?roomType=${encodeURIComponent(roomType)}` : '';
      const rows = await api.get<EligibleStudent[]>(`/deposits/eligible-students${params}`);
      setEligibleStudents(rows);
      setSelectedEligibleStudentIds(rows.map((item) => item.studentId));
    } catch (e: any) {
      message.error(e?.message || '加载在住人员失败');
    } finally {
      setEligibleLoading(false);
    }
  }, []);

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

  useEffect(() => {
    fetchEligibleStudents(filterRoomType);
  }, [fetchEligibleStudents, filterRoomType]);

  const depositByStudentId = useMemo(() => {
    const map = new Map<number, DepositRecord>();
    data.forEach((item) => map.set(item.studentId, item));
    return map;
  }, [data]);

  const filteredData = useMemo(() => {
    if (filterRoomType) {
      const s = searchText.trim().toLowerCase();
      return eligibleStudents
        .filter(
          (item) =>
            !s ||
            item.studentName.toLowerCase().includes(s) ||
            item.studentNo?.toLowerCase().includes(s),
        )
        .map((item) => {
          const deposit = depositByStudentId.get(item.studentId);
          return {
            id: deposit?.id ?? `eligible-${item.studentId}`,
            studentId: item.studentId,
            amount: deposit?.amount ?? item.depositAmount ?? 0,
            status: deposit?.status ?? 'unpaid',
            paidDate: deposit?.paidDate ?? '',
            refundDate: deposit?.refundDate,
            notes: deposit?.notes,
            installments: deposit?.installments ?? [],
            student: {
              id: item.studentId,
              name: item.studentName,
              studentNo: item.studentNo,
              roomType: item.roomType,
            },
            roomNumber: item.roomNumber,
            building: item.building,
            roomType: item.roomType,
          };
        });
    }

    return data.filter((d) => {
      if (searchText) {
        const s = searchText.toLowerCase();
        if (!d.student?.name?.toLowerCase().includes(s)) return false;
      }
      if (filterStatus && d.status !== filterStatus) return false;
      return true;
    });
  }, [data, depositByStudentId, eligibleStudents, filterRoomType, filterStatus, searchText]);

  const studentOptions = useMemo(() => buildDepositStudentOptions(students), [students]);

  const openBatchModal = (roomType = filterRoomType || '四人间') => {
    const amount = suggestedDepositByRoomType[roomType] ?? 100;
    setBatchRoomType(roomType);
    batchForm.resetFields();
    batchForm.setFieldsValue({ roomType, amount, paidDate: dayjs() });
    setBatchModal(true);
    fetchEligibleStudents(roomType);
  };

  const handleBatchRoomTypeChange = (roomType: string) => {
    setBatchRoomType(roomType);
    batchForm.setFieldsValue({
      amount: suggestedDepositByRoomType[roomType] ?? batchForm.getFieldValue('amount') ?? 100,
    });
    fetchEligibleStudents(roomType);
  };

  const handleCreate = async () => {
    setSaving(true);
    try {
      const values = await createForm.validateFields();
      await api.post('/deposits', {
        studentId: values.studentId,
        amount: values.amount,
        paidDate: values.paidDate.format('YYYY-MM-DD'),
        notes: values.notes,
      });
      message.success('押金金额已增加');
      setCreateModal(false);
      createForm.resetFields();
      fetchData();
      fetchEligibleStudents(filterRoomType);
    } catch (e: any) {
      if (!isFormValidationError(e)) {
        message.error(e?.message || '操作失败');
      }
    } finally {
      setSaving(false);
    }
  };

  const handleBatchCreate = async () => {
    if (selectedEligibleStudentIds.length === 0) {
      message.warning('请选择至少一名学生');
      return;
    }
    setSaving(true);
    try {
      const values = await batchForm.validateFields();
      await api.post('/deposits/batch', {
        studentIds: selectedEligibleStudentIds,
        amount: values.amount,
        paidDate: values.paidDate.format('YYYY-MM-DD'),
        notes: values.notes,
        roomType: values.roomType,
      });
      message.success(`已为 ${selectedEligibleStudentIds.length} 人批量收取押金`);
      setBatchModal(false);
      batchForm.resetFields();
      await fetchData();
      fetchEligibleStudents(filterRoomType);
    } catch (e: any) {
      if (!isFormValidationError(e)) {
        message.error(e?.message || '操作失败');
      }
    } finally {
      setSaving(false);
    }
  };

  const handleRefund = async () => {
    if (!refundModal) return;
    setSaving(true);
    try {
      const values = await refundForm.validateFields();
      await api.put(`/deposits/${refundModal.id}/refund`, {
        refundDate: values.refundDate.format('YYYY-MM-DD'),
        notes: values.notes,
      });
      message.success('退还操作完成');
      setRefundModal(null);
      refundForm.resetFields();
      fetchData();
      fetchEligibleStudents(filterRoomType);
    } catch (e: any) {
      if (!isFormValidationError(e)) {
        message.error(e?.message || '操作失败');
      }
    } finally {
      setSaving(false);
    }
  };

  const handleAddInstallment = async () => {
    if (installmentModal == null) return;
    try {
      const values = await installmentForm.validateFields();
      await api.post(`/deposits/${installmentModal}/installments`, {
        amount: values.amount,
        dueDate: values.dueDate.format('YYYY-MM-DD'),
      });
      message.success('分期已添加');
      setInstallmentModal(null);
      installmentForm.resetFields();
      fetchData();
    } catch (e: any) {
      if (!isFormValidationError(e)) {
        message.error(e?.message || '操作失败');
      }
    }
  };

  const handlePayInstallment = async (installmentId: number) => {
    try {
      await api.put(`/deposits/installments/${installmentId}`, {
        paidDate: dayjs().format('YYYY-MM-DD'),
        status: 'paid',
      });
      message.success('分期已标记为已缴');
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    }
  };

  const saveInstallmentCell = async (
    installmentId: number,
    field: 'status' | 'paidDate',
    value: unknown,
  ) => {
    await api.put(`/deposits/installments/${installmentId}`, { [field]: value });
    message.success('分期记录已保存');
    if (detailModal) {
      const refreshed = await api.get<DepositRecord>(`/deposits/${detailModal.id}`);
      setDetailModal(refreshed);
    }
    await fetchData();
  };

  const handleDeleteInstallment = async (installmentId: number) => {
    try {
      await api.delete(`/deposits/installments/${installmentId}`);
      message.success('分期已归档');
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    }
  };

  const columns = useMemo(
    () => [
      { title: '学生', width: 120, render: (_: unknown, r: any) => r.student?.name || '-' },
      {
        title: '当前可用押金',
        dataIndex: 'amount',
        width: 130,
        render: (v: number) => `¥${Number(v || 0).toFixed(2)}`,
      },
      {
        title: '房间',
        width: 120,
        render: (_: unknown, r: any) =>
          r.roomNumber ? `${r.building ? `${r.building}-` : ''}${r.roomNumber}` : '-',
      },
      { title: '房型', dataIndex: 'roomType', width: 100, render: (v: string) => v || '-' },
      { title: '最近收取日期', dataIndex: 'paidDate', width: 120, render: (v: string) => v || '-' },
      {
        title: '状态',
        dataIndex: 'status',
        render: (s: string) =>
          s === 'unpaid' ? (
            <Tag color="default">未缴</Tag>
          ) : (
            <Tag color={statusMap[s]?.color}>{statusMap[s]?.text || s}</Tag>
          ),
      },
      { title: '退还日期', dataIndex: 'refundDate', width: 110, render: (v: unknown) => v || '-' },
      { title: '备注', dataIndex: 'notes', width: 120, render: (v: unknown) => v || '-' },
      {
        title: '操作',
        width: 240,
        render: (_: unknown, record: any) => {
          const hasDeposit = typeof record.id === 'number';
          return (
            <Space>
              {hasDeposit && (
                <PermissionButton
                  permission="deposit:view"
                  size="small"
                  onClick={() => {
                    setDetailModal(record);
                  }}
                >
                  详情
                </PermissionButton>
              )}
              {record.status === 'paid' && hasDeposit && (
                <PermissionButton
                  permission="deposit:refund"
                  size="small"
                  type="primary"
                  onClick={() => {
                    setRefundModal(record);
                    refundForm.setFieldsValue({ refundDate: dayjs() });
                  }}
                >
                  退还
                </PermissionButton>
              )}
              {hasDeposit && (
                <Popconfirm
                  title="确定归档？"
                  onConfirm={async () => {
                    try {
                      await api.delete(`/deposits/${record.id}`);
                      message.success('归档成功');
                      fetchData();
                      fetchEligibleStudents(filterRoomType);
                    } catch (e: any) {
                      message.error(e?.message || '归档失败');
                    }
                  }}
                >
                  <PermissionButton
                    permission="deposit:delete"
                    size="small"
                    danger
                    icon={<InboxOutlined />}
                  >
                    归档
                  </PermissionButton>
                </Popconfirm>
              )}
            </Space>
          );
        },
      },
    ],
    [fetchData, fetchEligibleStudents, filterRoomType, refundForm],
  );

  const eligibleColumns = [
    {
      title: '学生',
      render: (_: unknown, r: EligibleStudent) =>
        `${r.studentName} (${r.studentNo || `#${r.studentId}`})`,
    },
    {
      title: '房间',
      render: (_: unknown, r: EligibleStudent) =>
        `${r.building ? `${r.building}-` : ''}${r.roomNumber}`,
    },
    { title: '房型', dataIndex: 'roomType' },
    {
      title: '当前押金',
      dataIndex: 'depositAmount',
      render: (v: number) => `¥${Number(v || 0).toFixed(2)}`,
    },
  ];

  return (
    <div>
      <div
        style={{
          marginBottom: 16,
          display: 'flex',
          justifyContent: 'space-between',
          flexWrap: 'wrap',
          gap: 8,
        }}
      >
        <Space wrap>
          <Input.Search
            placeholder="搜索学生姓名/学号"
            allowClear
            style={{ width: 180 }}
            onSearch={(v) => setSearchText(v)}
            onChange={(e) => {
              setSearchText(e.target.value);
            }}
          />
          <Select
            placeholder="房型筛选"
            allowClear
            style={{ width: 130 }}
            value={filterRoomType}
            onChange={(v) => setFilterRoomType(v)}
            options={roomTypeOptions}
          />
          <Select
            placeholder="状态筛选"
            allowClear
            style={{ width: 120 }}
            value={filterStatus}
            disabled={!!filterRoomType}
            onChange={(v) => setFilterStatus(v)}
            options={[
              { value: 'paid', label: '有余额' },
              { value: 'refunded', label: '已全退' },
              { value: 'depleted', label: '已扣完' },
            ]}
          />
        </Space>
        <Space wrap>
          <PermissionButton
            permission="deposit:create"
            icon={<TeamOutlined />}
            onClick={() => openBatchModal()}
          >
            按房型批量收取
          </PermissionButton>
          <PermissionButton
            permission="deposit:create"
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => {
              createForm.resetFields();
              createForm.setFieldsValue({ amount: 500, paidDate: dayjs() });
              setCreateModal(true);
            }}
          >
            收取押金
          </PermissionButton>
        </Space>
      </div>
      <Table
        columns={columns}
        dataSource={filteredData}
        rowKey="id"
        loading={loading || (!!filterRoomType && eligibleLoading)}
        scroll={{ x: 1200 }}
        pagination={{
          defaultPageSize: 15,
          showSizeChanger: true,
          pageSizeOptions: [15, 30, 50, 100],
          showTotal: (total) => `共 ${total} 条`,
        }}
        locale={{ emptyText: <Empty description="暂无数据" /> }}
      />

      {/* Batch Create Modal */}
      <Modal
        title="按房型批量收取押金"
        open={batchModal}
        onOk={handleBatchCreate}
        onCancel={() => setBatchModal(false)}
        okText="确认批量收取"
        confirmLoading={saving}
        okButtonProps={{ disabled: selectedEligibleStudentIds.length === 0 }}
        width={760}
      >
        <Form form={batchForm} layout="vertical">
          <Space style={{ width: '100%' }} align="start" wrap>
            <Form.Item
              name="roomType"
              label="房型"
              rules={[{ required: true, message: '请选择房型' }]}
            >
              <Select
                style={{ width: 140 }}
                options={roomTypeOptions}
                onChange={handleBatchRoomTypeChange}
              />
            </Form.Item>
            <Form.Item
              name="amount"
              label="每人收取金额（元）"
              rules={[{ required: true, message: '请输入金额' }]}
            >
              <InputNumber min={0.01} precision={2} style={{ width: 180 }} />
            </Form.Item>
            <Form.Item
              name="paidDate"
              label="收取日期"
              rules={[{ required: true, message: '请选择日期' }]}
            >
              <DatePicker style={{ width: 180 }} placeholder="选择收取日期" format="YYYY-MM-DD" />
            </Form.Item>
          </Space>
          <Form.Item name="notes" label="备注">
            <Input.TextArea rows={2} placeholder={`${batchRoomType}押金`} />
          </Form.Item>
        </Form>
        <div style={{ marginBottom: 8 }}>
          已选择 <strong>{selectedEligibleStudentIds.length}</strong> / {eligibleStudents.length} 人
          {suggestedDepositByRoomType[batchRoomType] && (
            <span style={{ color: '#999', marginLeft: 8 }}>
              建议金额：¥{suggestedDepositByRoomType[batchRoomType]}
            </span>
          )}
        </div>
        <Table
          size="small"
          columns={eligibleColumns}
          dataSource={eligibleStudents}
          rowKey="studentId"
          loading={eligibleLoading}
          locale={{ emptyText: <Empty description="暂无符合条件的在住人员" /> }}
          pagination={{ pageSize: 6, showSizeChanger: false }}
          rowSelection={{
            selectedRowKeys: selectedEligibleStudentIds,
            onChange: (keys) => setSelectedEligibleStudentIds(keys as number[]),
          }}
        />
      </Modal>

      {/* Create Modal */}
      <Modal
        title="收取押金"
        open={createModal}
        onOk={handleCreate}
        onCancel={() => setCreateModal(false)}
        okText="确认"
        confirmLoading={saving}
      >
        <Form form={createForm} layout="vertical">
          <Form.Item
            name="studentId"
            label="学生"
            rules={[{ required: true, message: '请选择学生' }]}
          >
            <Select
              showSearch
              optionFilterProp="label"
              placeholder="搜索并选择学生"
              options={studentOptions}
            />
          </Form.Item>
          <Form.Item name="amount" label="本次收取金额（元）" rules={[{ required: true }]}>
            <InputNumber min={0.01} precision={2} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="paidDate" label="收取日期" rules={[{ required: true }]}>
            <DatePicker style={{ width: '100%' }} placeholder="选择收取日期" format="YYYY-MM-DD" />
          </Form.Item>
          <Form.Item name="notes" label="备注">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>

      {/* Refund Modal */}
      <Modal
        title={`退还押金 - ${refundModal?.student?.name}`}
        open={!!refundModal}
        onOk={handleRefund}
        onCancel={() => setRefundModal(null)}
        okText="确认退还"
        confirmLoading={saving}
      >
        <Form form={refundForm} layout="vertical">
          <div style={{ marginBottom: 16, padding: 12, background: '#f5f5f5', borderRadius: 8 }}>
            当前可用押金: <strong>¥{Number(refundModal?.amount || 0).toFixed(2)}</strong>
          </div>
          <Form.Item name="refundDate" label="退还日期" rules={[{ required: true }]}>
            <DatePicker style={{ width: '100%' }} placeholder="选择退还日期" format="YYYY-MM-DD" />
          </Form.Item>
          <Form.Item name="notes" label="备注">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>

      {/* Detail Modal */}
      <Modal
        title={`押金详情 - ${detailModal?.student?.name}`}
        open={!!detailModal}
        onCancel={() => setDetailModal(null)}
        footer={null}
        width={640}
      >
        {detailModal && (
          <div>
            <Card size="small" style={{ marginBottom: 16 }}>
              <p>
                <strong>当前可用押金:</strong> ¥{Number(detailModal.amount).toFixed(2)}
              </p>
              <p>
                <strong>最近收取日期:</strong> {detailModal.paidDate}
              </p>
              <p>
                <strong>状态:</strong>{' '}
                <Tag color={statusMap[detailModal.status]?.color}>
                  {statusMap[detailModal.status]?.text || detailModal.status}
                </Tag>
              </p>
              {detailModal.notes && (
                <p>
                  <strong>备注:</strong> {detailModal.notes}
                </p>
              )}
            </Card>

            {/* Installments Section */}
            <div
              style={{
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
                marginBottom: 8,
              }}
            >
              <h4 style={{ margin: 0 }}>分期记录</h4>
              <PermissionButton
                permission="deposit:edit"
                size="small"
                type="primary"
                icon={<PlusOutlined />}
                onClick={() => {
                  setInstallmentModal(detailModal.id);
                  installmentForm.resetFields();
                }}
              >
                添加分期
              </PermissionButton>
            </div>
            {detailModal.installments && detailModal.installments.length > 0 ? (
              <Table
                size="small"
                pagination={false}
                rowKey="id"
                dataSource={detailModal.installments}
                columns={[
                  {
                    title: '金额',
                    dataIndex: 'amount',
                    render: (value: number) => `¥${Number(value).toFixed(2)}`,
                  },
                  { title: '到期日', dataIndex: 'dueDate' },
                  {
                    title: '实付日',
                    dataIndex: 'paidDate',
                    render: (value: string, item: any) => (
                      <EditableCell
                        value={value}
                        editor="date"
                        permission="deposit:edit"
                        onSave={(next) => saveInstallmentCell(item.id, 'paidDate', next)}
                      >
                        {value || '-'}
                      </EditableCell>
                    ),
                  },
                  {
                    title: '状态',
                    dataIndex: 'status',
                    render: (value: string, item: any) => (
                      <EditableCell
                        value={value}
                        editor="select"
                        options={[
                          { value: 'pending', label: '待缴' },
                          { value: 'paid', label: '已缴' },
                          { value: 'overdue', label: '逾期' },
                        ]}
                        permission="deposit:edit"
                        onSave={(next) => saveInstallmentCell(item.id, 'status', next)}
                      >
                        <Tag color={installmentStatusMap[value]?.color}>
                          {installmentStatusMap[value]?.text || value}
                        </Tag>
                      </EditableCell>
                    ),
                  },
                  {
                    title: '操作',
                    render: (_: unknown, item: any) => (
                      <Space>
                        {item.status === 'pending' && (
                          <PermissionButton
                            permission="deposit:edit"
                            size="small"
                            type="primary"
                            icon={<DollarOutlined />}
                            onClick={() => handlePayInstallment(item.id)}
                          >
                            标记已缴
                          </PermissionButton>
                        )}
                        <Popconfirm
                          title="确定归档？"
                          onConfirm={() => handleDeleteInstallment(item.id)}
                        >
                          <PermissionButton
                            permission="deposit:delete"
                            size="small"
                            danger
                            icon={<InboxOutlined />}
                          >
                            归档
                          </PermissionButton>
                        </Popconfirm>
                      </Space>
                    ),
                  },
                ]}
              />
            ) : (
              <p style={{ color: '#999' }}>暂无分期记录</p>
            )}
          </div>
        )}
      </Modal>

      {/* Add Installment Modal */}
      <Modal
        title="添加分期"
        open={installmentModal != null}
        onOk={handleAddInstallment}
        onCancel={() => setInstallmentModal(null)}
        okText="确认"
      >
        <Form form={installmentForm} layout="vertical">
          <Form.Item name="amount" label="分期金额（元）" rules={[{ required: true }]}>
            <InputNumber min={0.01} precision={2} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="dueDate" label="到期日期" rules={[{ required: true }]}>
            <DatePicker style={{ width: '100%' }} placeholder="选择到期日期" format="YYYY-MM-DD" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default DepositsPage;
