import React, { useEffect, useState, useMemo, useCallback } from 'react';
import {
  Table,
  Button,
  Modal,
  Form,
  Input,
  InputNumber,
  Select,
  Space,
  Tag,
  Popconfirm,
  Badge,
  Upload,
  Drawer,
  Tabs,
  Empty,
} from 'antd';
import type { UploadRequestError, UploadRequestOption } from '@rc-component/upload/lib/interface';
import {
  PlusOutlined,
  UploadOutlined,
  DownloadOutlined,
  UndoOutlined,
  InboxOutlined,
  SearchOutlined,
  ExportOutlined,
} from '@ant-design/icons';
import api from '../../api';
import { downloadBlob } from '../../utils/download';
import PermissionButton from '../../components/PermissionButton';
import EditableCell from '../../components/EditableCell';
import { message } from '../../ui/app-message';

const statusMap: Record<string, { text: string; color: string }> = {
  available: { text: '可入住', color: 'green' },
  full: { text: '已满', color: 'red' },
  maintenance: { text: '维修中', color: 'orange' },
  archived: { text: '已归档', color: '#999' },
};

interface BedItem {
  id: number;
  bedNumber: string;
  status: string;
  notes?: string | null;
}

interface LockerItem {
  id: number;
  lockerNumber: string;
  status: string;
  notes?: string | null;
}

function parseRoomNumber(input: string) {
  const cleaned = input.replace(/[（(].*?[）)]/g, '').trim();
  const familyMatch = cleaned.match(/^(\d+)-(\d+)-(\d+)$/);
  if (familyMatch) {
    return {
      building: `${familyMatch[1]}-${familyMatch[2]}栋`,
      floor: parseInt(familyMatch[3].charAt(0), 10) || undefined,
      roomType: '家庭房',
      capacity: 4,
    };
  }
  const stdMatch = cleaned.match(/^(\d+)-(\d+)$/);
  if (stdMatch) {
    const bldgNum = stdMatch[1];
    const roomPart = stdMatch[2];
    const floor = parseInt(roomPart.charAt(0), 10) || undefined;
    let roomType = '四人间';
    let capacity = 4;
    if (bldgNum === '2') {
      roomType = '单人间';
      capacity = 1;
    } else if (bldgNum === '8') {
      roomType = '爆改房';
      capacity = 2;
    }
    return { building: `${bldgNum}号楼`, floor, roomType, capacity };
  }
  return null;
}

const RoomsPage: React.FC = () => {
  const [data, setData] = useState<any[]>([]);
  const [loading, setLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [editing, setEditing] = useState<any>(null);
  const [showArchived, setShowArchived] = useState(false);
  const [archivedCount, setArchivedCount] = useState(0);
  const [searchText, setSearchText] = useState('');
  const [filterBuilding, setFilterBuilding] = useState<string | undefined>(undefined);
  const [filterStatus, setFilterStatus] = useState<string | undefined>(undefined);
  const [filterRentalCategory, setFilterRentalCategory] = useState<string | undefined>(undefined);
  const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
  const [saving, setSaving] = useState(false);
  const [form] = Form.useForm();
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [drawerRoom, setDrawerRoom] = useState<any>(null);
  const [beds, setBeds] = useState<any[]>([]);
  const [lockers, setLockers] = useState<any[]>([]);
  const [bedModalOpen, setBedModalOpen] = useState(false);
  const [bedEditing, setBedEditing] = useState<any>(null);
  const [lockerModalOpen, setLockerModalOpen] = useState(false);
  const [lockerEditing, setLockerEditing] = useState<any>(null);
  const [bedForm] = Form.useForm();
  const [lockerForm] = Form.useForm();
  const [savingBed, setSavingBed] = useState(false);
  const [savingLocker, setSavingLocker] = useState(false);
  const [batchLoading, setBatchLoading] = useState(false);

  const handleBatchDelete = async () => {
    setBatchLoading(true);
    try {
      const res: any = await api.post('/rooms/batch-delete', { ids: selectedRowKeys });
      message.success(res?.message || `已批量归档 ${selectedRowKeys.length} 间`);
      setSelectedRowKeys([]);
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '批量归档失败');
    } finally {
      setBatchLoading(false);
    }
  };

  const fetchData = async () => {
    setLoading(true);
    try {
      const params: any = { includeArchived: 'true' };
      const res: any = await api.get('/rooms/overview', { params });
      const archived = res.filter((r: any) => r.status === 'archived');
      setArchivedCount(archived.length);
      const filtered = showArchived ? res : res.filter((r: any) => r.status !== 'archived');
      setData(filtered);
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '加载失败，请稍后重试');
    }
    setLoading(false);
  };

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

  // 获取楼栋列表用于筛选
  const buildings = useMemo(() => {
    const set = new Set(data.map((r: any) => r.building).filter(Boolean));
    return [...set].sort();
  }, [data]);

  // 前端搜索和楼栋筛选
  const filteredData = useMemo(() => {
    let result = data;
    if (searchText) {
      const keyword = searchText.toLowerCase();
      result = result.filter(
        (r: Record<string, unknown>) =>
          typeof r.roomNumber === 'string' && r.roomNumber.toLowerCase().includes(keyword),
      );
    }
    if (filterBuilding)
      result = result.filter((r: Record<string, unknown>) => r.building === filterBuilding);
    if (filterStatus)
      result = result.filter((r: Record<string, unknown>) => r.status === filterStatus);
    if (filterRentalCategory) {
      result = result.filter(
        (r: Record<string, unknown>) => r.rentalCategory === filterRentalCategory,
      );
    }
    return result;
  }, [data, searchText, filterBuilding, filterStatus, filterRentalCategory]);
  const remainingBedSlots = useMemo(() => {
    const capacity = Number(drawerRoom?.capacity) || 0;
    return Math.max(capacity - beds.length, 0);
  }, [drawerRoom?.capacity, beds.length]);
  const defaultBatchBedCount = Math.min(4, Math.max(remainingBedSlots, 1));

  const handleSave = async () => {
    const values = await form.validateFields();
    const payload = values;
    setSaving(true);
    try {
      if (editing) {
        await api.put(`/rooms/${editing.id}`, payload);
        message.success('更新成功');
      } else {
        await api.post('/rooms', payload);
        message.success(`创建成功，已自动生成 ${values.capacity} 张床位`);
      }
      setModalOpen(false);
      form.resetFields();
      setEditing(null);
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setSaving(false);
    }
  };

  const saveRoomCell = async (record: any, field: string, value: unknown) => {
    await api.put(`/rooms/${record.id}`, { [field]: value });
    message.success('已保存');
    await fetchData();
  };

  const saveBedCell = async (record: BedItem, field: string, value: unknown) => {
    if (!drawerRoom) return;
    await api.put(`/rooms/${drawerRoom.id}/beds/${record.id}`, { [field]: value });
    message.success('已保存');
    await fetchBeds(drawerRoom.id);
  };

  const saveLockerCell = async (record: LockerItem, field: string, value: unknown) => {
    if (!drawerRoom) return;
    await api.put(`/rooms/${drawerRoom.id}/lockers/${record.id}`, { [field]: value });
    message.success('已保存');
    await fetchLockers(drawerRoom.id);
  };
  const fetchBeds = useCallback(async (roomId: number) => {
    try {
      const res = await api.get<BedItem[]>(`/rooms/${roomId}/beds`);
      setBeds(res);
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '加载床位失败');
    }
  }, []);

  const fetchLockers = useCallback(async (roomId: number) => {
    try {
      const res = await api.get<LockerItem[]>(`/rooms/${roomId}/lockers`);
      setLockers(res);
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '加载柜子失败');
    }
  }, []);

  const handleSaveBed = async () => {
    const values = await bedForm.validateFields();
    setSavingBed(true);
    try {
      if (bedEditing) {
        await api.put(`/rooms/${drawerRoom.id}/beds/${bedEditing.id}`, values);
      } else {
        await api.post(`/rooms/${drawerRoom.id}/beds`, values);
      }
      message.success(bedEditing ? '更新成功' : '添加成功');
      setBedModalOpen(false);
      bedForm.resetFields();
      setBedEditing(null);
      fetchBeds(drawerRoom.id);
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setSavingBed(false);
    }
  };

  const handleDeleteBed = async (id: number) => {
    try {
      await api.delete(`/rooms/${drawerRoom.id}/beds/${id}`);
      message.success('已归档');
      fetchBeds(drawerRoom.id);
    } catch (e: any) {
      message.error(e?.message || '归档失败');
    }
  };

  const handleBatchBeds = async (count: number) => {
    try {
      await api.post(`/rooms/${drawerRoom.id}/beds/batch`, { count });
      message.success(`已生成 ${count} 张床位`);
      fetchBeds(drawerRoom.id);
    } catch (e: any) {
      message.error(e?.message || '批量生成失败');
    }
  };

  const handleSaveLocker = async () => {
    const values = await lockerForm.validateFields();
    setSavingLocker(true);
    try {
      if (lockerEditing) {
        await api.put(`/rooms/${drawerRoom.id}/lockers/${lockerEditing.id}`, values);
      } else {
        await api.post(`/rooms/${drawerRoom.id}/lockers`, values);
      }
      message.success(lockerEditing ? '更新成功' : '添加成功');
      setLockerModalOpen(false);
      lockerForm.resetFields();
      setLockerEditing(null);
      fetchLockers(drawerRoom.id);
    } catch (e: any) {
      message.error(e?.message || '操作失败');
    } finally {
      setSavingLocker(false);
    }
  };

  const handleDeleteLocker = async (id: number) => {
    try {
      await api.delete(`/rooms/${drawerRoom.id}/lockers/${id}`);
      message.success('已归档');
      fetchLockers(drawerRoom.id);
    } catch (e: any) {
      message.error(e?.message || '归档失败');
    }
  };

  const handleBatchLockers = async (count: number) => {
    try {
      await api.post(`/rooms/${drawerRoom.id}/lockers/batch`, { count });
      message.success(`已生成 ${count} 个柜子`);
      fetchLockers(drawerRoom.id);
    } catch (e: any) {
      message.error(e?.message || '批量生成失败');
    }
  };

  const handleArchive = async (id: number) => {
    try {
      await api.delete(`/rooms/${id}`);
      message.success('已归档');
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '归档失败');
    }
  };

  const handleRestore = async (id: number) => {
    try {
      await api.put(`/rooms/${id}/restore`);
      message.success('已恢复');
      fetchData();
    } catch (e: any) {
      message.error(e?.message || '恢复失败');
    }
  };

  const handleDownloadTemplate = () => {
    downloadBlob('/rooms/template', '房间导入模板.xlsx').catch(() => message.error('下载失败'));
  };

  const handleExport = () => {
    const params = showArchived ? '?includeArchived=true' : '';
    downloadBlob('/rooms/export' + params, '房间列表.xlsx').catch(() => message.error('导出失败'));
  };

  const columns = useMemo(
    () => [
      {
        title: '房间号',
        dataIndex: 'roomNumber',
        width: 100,
        sorter: (a: any, b: any) => a.roomNumber.localeCompare(b.roomNumber),
        render: (v: string, r: any) => (
          <EditableCell
            value={v}
            required
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'roomNumber', next)}
          >
            {v}
          </EditableCell>
        ),
      },
      {
        title: '楼栋',
        dataIndex: 'building',
        width: 80,
        render: (v: string, r: any) => (
          <EditableCell
            value={v}
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'building', next)}
          >
            {v || '-'}
          </EditableCell>
        ),
      },
      {
        title: '楼层',
        dataIndex: 'floor',
        width: 80,
        render: (v: number, r: any) => (
          <EditableCell
            value={v}
            editor="number"
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'floor', next)}
          >
            {v ?? '-'}
          </EditableCell>
        ),
      },
      {
        title: '类型',
        dataIndex: 'roomType',
        width: 90,
        render: (v: any, r: any) => (
          <EditableCell
            value={v}
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'roomType', next)}
          >
            {v || '-'}
          </EditableCell>
        ),
      },
      {
        title: '租赁类型',
        dataIndex: 'rentalCategory',
        width: 100,
        render: (v: string, r: any) => (
          <EditableCell
            value={v}
            editor="select"
            options={[
              { value: 'long', label: '长租' },
              { value: 'short', label: '短租' },
            ]}
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'rentalCategory', next)}
          >
            {(() => {
              if (v === 'long') return <Tag color="blue">长租</Tag>;
              if (v === 'short') return <Tag color="green">短租</Tag>;
              return '-';
            })()}
          </EditableCell>
        ),
      },
      {
        title: '月租金',
        dataIndex: 'monthlyRate',
        width: 100,
        render: (v: number, r: any) => (
          <EditableCell
            value={v}
            editor="money"
            min={0}
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'monthlyRate', next)}
          >
            {v ? `¥${v}` : '-'}
          </EditableCell>
        ),
      },
      {
        title: '额定人数',
        dataIndex: 'capacity',
        width: 80,
        render: (v: number, r: any) => (
          <EditableCell
            value={v}
            editor="number"
            min={1}
            required
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'capacity', next)}
          >
            {v}
          </EditableCell>
        ),
      },
      {
        title: '当前入住',
        width: 80,
        render: (_: any, r: any) =>
          r.status === 'archived' ? (
            <Tag color="#999">-</Tag>
          ) : (
            <Badge
              count={r.currentCount}
              showZero
              overflowCount={99}
              style={{ backgroundColor: r.currentCount >= r.capacity ? '#ff4d4f' : '#52c41a' }}
            />
          ),
      },
      {
        title: '状态',
        dataIndex: 'status',
        width: 80,
        render: (s: string, r: any) => (
          <EditableCell
            value={s}
            editor="select"
            options={[
              { value: 'available', label: '可入住' },
              { value: 'full', label: '已满' },
              { value: 'maintenance', label: '维修中' },
            ]}
            permission="room:edit"
            disabled={r.status === 'archived'}
            onSave={(next) => saveRoomCell(r, 'status', next)}
          >
            <Tag color={statusMap[s]?.color}>{statusMap[s]?.text || s}</Tag>
          </EditableCell>
        ),
      },
      {
        title: '操作',
        width: 220,
        render: (_: unknown, record: unknown) => {
          const r = record as { status?: string; id: number };
          return (
            <Space>
              {r.status === 'archived' ? (
                <Popconfirm title="确定恢复此宿舍？" onConfirm={() => handleRestore(r.id)}>
                  <PermissionButton
                    permission="room:edit"
                    size="small"
                    icon={<UndoOutlined />}
                    type="link"
                  >
                    恢复
                  </PermissionButton>
                </Popconfirm>
              ) : (
                <>
                  <PermissionButton
                    permission="room:view"
                    size="small"
                    type="link"
                    onClick={async () => {
                      const rec = record as { id: number };
                      setDrawerRoom(record);
                      setDrawerOpen(true);
                      await Promise.all([fetchBeds(rec.id), fetchLockers(rec.id)]);
                    }}
                  >
                    查看
                  </PermissionButton>
                  <PermissionButton
                    permission="room:edit"
                    size="small"
                    onClick={() => {
                      const rec = record as { id: number };
                      setEditing(rec);
                      form.setFieldsValue(rec);
                      setModalOpen(true);
                    }}
                  >
                    编辑
                  </PermissionButton>
                  <Popconfirm title="确定归档？" onConfirm={() => handleArchive(r.id)}>
                    <PermissionButton
                      permission="room:delete"
                      size="small"
                      icon={<InboxOutlined />}
                    >
                      归档
                    </PermissionButton>
                  </Popconfirm>
                </>
              )}
            </Space>
          );
        },
      },
    ],
    [
      showArchived,
      buildings,
      handleBatchDelete,
      handleRestore,
      handleArchive,
      fetchBeds,
      fetchLockers,
    ],
  );

  return (
    <div>
      <div className="responsive-toolbar">
        <Space wrap className="responsive-toolbar__group">
          <h3 style={{ margin: 0 }}>宿舍管理</h3>
          <Input.Search
            placeholder="搜索房间号"
            onSearch={setSearchText}
            allowClear
            style={{ width: 160 }}
            prefix={<SearchOutlined />}
          />
          <Select
            placeholder="筛选楼栋"
            allowClear
            style={{ width: 120 }}
            onChange={(v) => setFilterBuilding(v)}
            options={buildings.map((b) => ({ value: b, label: b }))}
          />
          <Select
            placeholder="状态"
            allowClear
            style={{ width: 110 }}
            value={filterStatus}
            onChange={setFilterStatus}
            options={[
              { value: 'available', label: '可入住' },
              { value: 'full', label: '已满' },
              { value: 'maintenance', label: '维护中' },
            ]}
          />
          <Select
            placeholder="租赁类型"
            allowClear
            style={{ width: 120 }}
            value={filterRentalCategory}
            onChange={setFilterRentalCategory}
            options={[
              { value: 'long', label: '长租' },
              { value: 'short', label: '短租' },
            ]}
          />
          <Button
            type={showArchived ? 'primary' : 'default'}
            onClick={() => setShowArchived(!showArchived)}
          >
            {showArchived
              ? '隐藏已归档'
              : `显示已归档${archivedCount > 0 ? ` (${archivedCount})` : ''}`}
          </Button>
        </Space>
        <Space wrap className="responsive-toolbar__group">
          <Popconfirm
            title={`确定批量归档选中的 ${selectedRowKeys.length} 间宿舍？（有在住人员的会跳过）`}
            onConfirm={handleBatchDelete}
            okText="归档"
            cancelText="取消"
            disabled={selectedRowKeys.length === 0}
          >
            <PermissionButton
              permission="room:delete"
              danger
              icon={<InboxOutlined />}
              disabled={selectedRowKeys.length === 0}
              loading={batchLoading}
            >
              批量归档
            </PermissionButton>
          </Popconfirm>
          <PermissionButton
            permission="room:create"
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => {
              setEditing(null);
              form.resetFields();
              setModalOpen(true);
            }}
          >
            添加宿舍
          </PermissionButton>
          <Upload
            accept=".xlsx,.xls"
            showUploadList={false}
            customRequest={async (options: UploadRequestOption<{ message?: string }>) => {
              const { file, onSuccess, onError } = options;
              if (typeof file === 'string') {
                message.error('不支持字符串文件');
                return;
              }
              try {
                const formData = new FormData();
                formData.append('file', file);
                const res = await api.post<{ message?: string }>('/rooms/import', formData, {
                  headers: { 'Content-Type': 'multipart/form-data' },
                });
                message.success(res.message || '导入成功');
                onSuccess?.(res);
                fetchData();
              } catch (e: unknown) {
                const err = e as { message?: string };
                message.error(err?.message || '导入失败');
                onError?.(e as UploadRequestError);
              }
            }}
          >
            <Button icon={<UploadOutlined />}>导入Excel</Button>
          </Upload>
          <PermissionButton
            permission="room:view"
            icon={<DownloadOutlined />}
            onClick={handleDownloadTemplate}
          >
            下载模板
          </PermissionButton>
          <PermissionButton permission="room:view" icon={<ExportOutlined />} onClick={handleExport}>
            导出列表
          </PermissionButton>
        </Space>
      </div>
      <Table
        columns={columns}
        dataSource={filteredData}
        rowKey="id"
        scroll={{ x: 1200 }}
        loading={loading}
        locale={{ emptyText: <Empty description="暂无数据" /> }}
        pagination={{
          defaultPageSize: 20,
          showSizeChanger: true,
          pageSizeOptions: [20, 50, 100],
          showTotal: (total) => `共 ${total} 间`,
        }}
        rowClassName={(record) => (record.status === 'archived' ? 'archived-row' : '')}
        rowSelection={{
          selectedRowKeys,
          onChange: (keys) => setSelectedRowKeys(keys as number[]),
          getCheckboxProps: (record: any) => ({ disabled: record.status === 'archived' }),
        }}
      />
      <style>{`.archived-row { opacity: 0.6; background: #fafafa !important; }`}</style>

      <Modal
        title={editing ? '编辑宿舍' : '添加宿舍'}
        open={modalOpen}
        onOk={handleSave}
        onCancel={() => {
          setModalOpen(false);
          setEditing(null);
        }}
        okText="保存"
        confirmLoading={saving}
      >
        <Form form={form} layout="vertical">
          <Form.Item name="roomNumber" label="房间号" rules={[{ required: true }]}>
            <Input
              placeholder="如：4-102（自动解析楼栋楼层）"
              onChange={(e) => {
                const parsed = parseRoomNumber(e.target.value);
                if (parsed) form.setFieldsValue(parsed);
              }}
            />
          </Form.Item>
          <Form.Item name="building" label="楼栋">
            <Input placeholder="如：4号楼（留空自动解析）" />
          </Form.Item>
          <Form.Item name="floor" label="楼层">
            <InputNumber min={1} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="capacity" label="额定人数" rules={[{ required: true }]}>
            <InputNumber min={1} max={20} style={{ width: '100%' }} />
          </Form.Item>
          <Form.Item name="roomType" label="宿舍类型">
            <Select
              allowClear
              options={[
                { value: '四人间', label: '四人间' },
                { value: '单人间', label: '单人间' },
                { value: '家庭房', label: '家庭房' },
                { value: '爆改房', label: '爆改房' },
              ]}
              placeholder="留空自动解析"
            />
          </Form.Item>
          <Form.Item name="rentalCategory" label="租赁类别">
            <Select
              allowClear
              options={[
                { value: 'short', label: '短租' },
                { value: 'long', label: '长租' },
              ]}
              placeholder="默认为短租"
            />
          </Form.Item>
          <Form.Item name="monthlyRate" label="月租金">
            <InputNumber min={0} precision={2} style={{ width: '100%' }} placeholder="长租月租金" />
          </Form.Item>
          {editing && (
            <Form.Item name="status" label="状态">
              <Select
                options={[
                  { value: 'available', label: '可入住' },
                  { value: 'full', label: '已满' },
                  { value: 'maintenance', label: '维修中' },
                ]}
              />
            </Form.Item>
          )}
        </Form>
      </Modal>

      <Drawer
        title={`${drawerRoom?.roomNumber} 房间详情`}
        open={drawerOpen}
        onClose={() => {
          setDrawerOpen(false);
          setDrawerRoom(null);
        }}
        width={640}
        destroyOnClose
      >
        <Tabs
          defaultActiveKey="info"
          items={[
            {
              key: 'info',
              label: '基本信息',
              children: drawerRoom && (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                  <div>
                    <strong>房间号：</strong>
                    {drawerRoom.roomNumber}
                  </div>
                  <div>
                    <strong>楼栋：</strong>
                    {drawerRoom.building || '-'}
                  </div>
                  <div>
                    <strong>楼层：</strong>
                    {drawerRoom.floor ?? '-'}
                  </div>
                  <div>
                    <strong>类型：</strong>
                    {drawerRoom.roomType || '-'}
                  </div>
                  <div>
                    <strong>额定人数：</strong>
                    {drawerRoom.capacity}
                  </div>
                  <div>
                    <strong>租赁类别：</strong>
                    {drawerRoom.rentalCategory === 'long' ? '长租' : '短租'}
                  </div>
                  <div>
                    <strong>月租金：</strong>
                    {drawerRoom.monthlyRate ? `¥${drawerRoom.monthlyRate}` : '-'}
                  </div>
                  <div>
                    <strong>状态：</strong>
                    <Tag color={statusMap[drawerRoom.status]?.color}>
                      {statusMap[drawerRoom.status]?.text}
                    </Tag>
                  </div>
                </div>
              ),
            },
            {
              key: 'beds',
              label: `床位管理 (${beds.length})`,
              children: (
                <div>
                  <div style={{ marginBottom: 12, display: 'flex', gap: 8 }}>
                    <Button
                      type="primary"
                      size="small"
                      icon={<PlusOutlined />}
                      disabled={drawerRoom?.status === 'archived' || remainingBedSlots === 0}
                      onClick={() => {
                        setBedEditing(null);
                        bedForm.resetFields();
                        setBedModalOpen(true);
                      }}
                    >
                      添加床位
                    </Button>
                    <Popconfirm
                      title={remainingBedSlots > 0 ? '批量生成床位' : '床位已达到额定人数'}
                      description={
                        remainingBedSlots > 0 ? (
                          <InputNumber
                            min={1}
                            max={remainingBedSlots}
                            defaultValue={defaultBatchBedCount}
                            id="batch-bed-count"
                            style={{ width: 80 }}
                          />
                        ) : (
                          '如需增加床位，请先调整宿舍额定人数'
                        )
                      }
                      onConfirm={() => {
                        const input = document.getElementById(
                          'batch-bed-count',
                        ) as HTMLInputElement;
                        handleBatchBeds(
                          input
                            ? parseInt(input.value) || defaultBatchBedCount
                            : defaultBatchBedCount,
                        );
                      }}
                      okText="生成"
                      disabled={drawerRoom?.status === 'archived' || remainingBedSlots === 0}
                    >
                      <Button
                        size="small"
                        disabled={drawerRoom?.status === 'archived' || remainingBedSlots === 0}
                      >
                        批量生成
                      </Button>
                    </Popconfirm>
                  </div>
                  <Table
                    dataSource={beds}
                    rowKey="id"
                    pagination={false}
                    size="small"
                    columns={[
                      {
                        title: '编号',
                        dataIndex: 'bedNumber',
                        width: 80,
                        render: (v: string, r: BedItem) => (
                          <EditableCell
                            value={v}
                            required
                            permission="room:edit"
                            disabled={drawerRoom?.status === 'archived'}
                            onSave={(next) => saveBedCell(r, 'bedNumber', next)}
                          >
                            {v}
                          </EditableCell>
                        ),
                      },
                      {
                        title: '状态',
                        dataIndex: 'status',
                        width: 80,
                        render: (s: string, r: BedItem) => (
                          <EditableCell
                            value={s}
                            editor="select"
                            options={[
                              { value: 'available', label: '空闲' },
                              { value: 'occupied', label: '占用' },
                              { value: 'maintenance', label: '维修' },
                            ]}
                            permission="room:edit"
                            disabled={drawerRoom?.status === 'archived'}
                            onSave={(next) => saveBedCell(r, 'status', next)}
                          >
                            {(() => {
                              const map: Record<string, { text: string; color: string }> = {
                                available: { text: '空闲', color: 'green' },
                                occupied: { text: '占用', color: 'blue' },
                                maintenance: { text: '维修', color: 'orange' },
                              };
                              return <Tag color={map[s]?.color}>{map[s]?.text || s}</Tag>;
                            })()}
                          </EditableCell>
                        ),
                      },
                      {
                        title: '备注',
                        dataIndex: 'notes',
                        render: (v: string, r: BedItem) => (
                          <EditableCell
                            value={v}
                            editor="textarea"
                            permission="room:edit"
                            disabled={drawerRoom?.status === 'archived'}
                            onSave={(next) => saveBedCell(r, 'notes', next)}
                          >
                            {v || '-'}
                          </EditableCell>
                        ),
                      },
                      {
                        title: '操作',
                        width: 120,
                        render: (_: any, r: any) => (
                          <Space size="small">
                            <PermissionButton
                              permission="room:edit"
                              size="small"
                              type="link"
                              disabled={drawerRoom?.status === 'archived'}
                              onClick={() => {
                                setBedEditing(r);
                                bedForm.setFieldsValue(r);
                                setBedModalOpen(true);
                              }}
                            >
                              编辑
                            </PermissionButton>
                            {r.status !== 'occupied' && (
                              <Popconfirm
                                title="确定归档？"
                                onConfirm={() => handleDeleteBed(r.id)}
                              >
                                <PermissionButton
                                  permission="room:edit"
                                  size="small"
                                  type="link"
                                  danger
                                  disabled={drawerRoom?.status === 'archived'}
                                >
                                  归档
                                </PermissionButton>
                              </Popconfirm>
                            )}
                          </Space>
                        ),
                      },
                    ]}
                  />
                </div>
              ),
            },
            {
              key: 'lockers',
              label: `柜子管理 (${lockers.length})`,
              children: (
                <div>
                  <div style={{ marginBottom: 12, display: 'flex', gap: 8 }}>
                    <Button
                      type="primary"
                      size="small"
                      icon={<PlusOutlined />}
                      disabled={drawerRoom?.status === 'archived'}
                      onClick={() => {
                        setLockerEditing(null);
                        lockerForm.resetFields();
                        setLockerModalOpen(true);
                      }}
                    >
                      添加柜子
                    </Button>
                    <Popconfirm
                      title="批量生成柜子"
                      description={
                        <InputNumber
                          min={1}
                          max={20}
                          defaultValue={4}
                          id="batch-locker-count"
                          style={{ width: 80 }}
                        />
                      }
                      onConfirm={() => {
                        const input = document.getElementById(
                          'batch-locker-count',
                        ) as HTMLInputElement;
                        handleBatchLockers(input ? parseInt(input.value) || 4 : 4);
                      }}
                      okText="生成"
                      disabled={drawerRoom?.status === 'archived'}
                    >
                      <Button size="small" disabled={drawerRoom?.status === 'archived'}>
                        批量生成
                      </Button>
                    </Popconfirm>
                  </div>
                  <Table
                    dataSource={lockers}
                    rowKey="id"
                    pagination={false}
                    size="small"
                    columns={[
                      {
                        title: '编号',
                        dataIndex: 'lockerNumber',
                        width: 80,
                        render: (v: string, r: LockerItem) => (
                          <EditableCell
                            value={v}
                            required
                            permission="room:edit"
                            disabled={drawerRoom?.status === 'archived'}
                            onSave={(next) => saveLockerCell(r, 'lockerNumber', next)}
                          >
                            {v}
                          </EditableCell>
                        ),
                      },
                      {
                        title: '状态',
                        dataIndex: 'status',
                        width: 80,
                        render: (s: string, r: LockerItem) => (
                          <EditableCell
                            value={s}
                            editor="select"
                            options={[
                              { value: 'available', label: '空闲' },
                              { value: 'occupied', label: '占用' },
                              { value: 'maintenance', label: '维修' },
                            ]}
                            permission="room:edit"
                            disabled={drawerRoom?.status === 'archived'}
                            onSave={(next) => saveLockerCell(r, 'status', next)}
                          >
                            {(() => {
                              const map: Record<string, { text: string; color: string }> = {
                                available: { text: '空闲', color: 'green' },
                                occupied: { text: '占用', color: 'blue' },
                                maintenance: { text: '维修', color: 'orange' },
                              };
                              return <Tag color={map[s]?.color}>{map[s]?.text || s}</Tag>;
                            })()}
                          </EditableCell>
                        ),
                      },
                      {
                        title: '备注',
                        dataIndex: 'notes',
                        render: (v: string, r: LockerItem) => (
                          <EditableCell
                            value={v}
                            editor="textarea"
                            permission="room:edit"
                            disabled={drawerRoom?.status === 'archived'}
                            onSave={(next) => saveLockerCell(r, 'notes', next)}
                          >
                            {v || '-'}
                          </EditableCell>
                        ),
                      },
                      {
                        title: '操作',
                        width: 120,
                        render: (_: any, r: any) => (
                          <Space size="small">
                            <PermissionButton
                              permission="room:edit"
                              size="small"
                              type="link"
                              disabled={drawerRoom?.status === 'archived'}
                              onClick={() => {
                                setLockerEditing(r);
                                lockerForm.setFieldsValue(r);
                                setLockerModalOpen(true);
                              }}
                            >
                              编辑
                            </PermissionButton>
                            {r.status !== 'occupied' && (
                              <Popconfirm
                                title="确定归档？"
                                onConfirm={() => handleDeleteLocker(r.id)}
                              >
                                <PermissionButton
                                  permission="room:edit"
                                  size="small"
                                  type="link"
                                  danger
                                  disabled={drawerRoom?.status === 'archived'}
                                >
                                  归档
                                </PermissionButton>
                              </Popconfirm>
                            )}
                          </Space>
                        ),
                      },
                    ]}
                  />
                </div>
              ),
            },
          ]}
        />
      </Drawer>

      <Modal
        title={bedEditing ? '编辑床位' : '添加床位'}
        open={bedModalOpen}
        onOk={handleSaveBed}
        onCancel={() => {
          setBedModalOpen(false);
          setBedEditing(null);
        }}
        confirmLoading={savingBed}
        okText="保存"
      >
        <Form form={bedForm} layout="vertical">
          <Form.Item name="bedNumber" label="床位编号" rules={[{ required: true }]}>
            <Input placeholder="如：1号床" />
          </Form.Item>
          <Form.Item name="status" label="状态">
            <Select
              options={[
                { value: 'available', label: '空闲' },
                { value: 'maintenance', label: '维修中' },
              ]}
              placeholder="默认为空闲"
            />
          </Form.Item>
          <Form.Item name="notes" label="备注">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>

      <Modal
        title={lockerEditing ? '编辑柜子' : '添加柜子'}
        open={lockerModalOpen}
        onOk={handleSaveLocker}
        onCancel={() => {
          setLockerModalOpen(false);
          setLockerEditing(null);
        }}
        confirmLoading={savingLocker}
        okText="保存"
      >
        <Form form={lockerForm} layout="vertical">
          <Form.Item name="lockerNumber" label="柜子编号" rules={[{ required: true }]}>
            <Input placeholder="如：1号柜" />
          </Form.Item>
          <Form.Item name="status" label="状态">
            <Select
              options={[
                { value: 'available', label: '空闲' },
                { value: 'maintenance', label: '维修中' },
              ]}
              placeholder="默认为空闲"
            />
          </Form.Item>
          <Form.Item name="notes" label="备注">
            <Input.TextArea rows={2} />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
};

export default RoomsPage;
