import React, { useState, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { validateResponse } from '../../utils/validate';
import { classroomScheduleSchema } from '../../api/schemas';
import {
  DatePicker,
  Card,
  Row,
  Col,
  Statistic,
  Tag,
  Space,
  Button,
  Modal,
  Spin,
  Empty,
  Tooltip,
} from 'antd';
import { CalendarOutlined, FileTextOutlined, ReadOutlined } from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import api from '../../api';
import { downloadBlob } from '../../utils/download';
import { message } from '../../ui/app-message';
import { getErrorMessage } from '../../utils/error';
import { QueryErrorState } from '../../components/QueryState';
import { useVisibleRefetch } from '../../hooks/usePageVisible';

interface ScheduleData {
  year: number;
  month: number;
  days: number;
  classrooms: any[];
  organizations: any[];
  matrix: Record<number, Record<number, any>>;
  summary: Record<
    number,
    { totalDays: number; rentedDays: number; idleDays: number; occupancyRate: number }
  >;
}

const ClassroomSchedulePage: React.FC = () => {
  const [month, setMonth] = useState<Dayjs>(dayjs());
  const [detailModal, setDetailModal] = useState<any>(null);

  const { data, isLoading, isFetching, isError, refetch } = useQuery<ScheduleData | null>({
    queryKey: ['classroom-rentals', 'schedule', month.year(), month.month()],
    queryFn: async () =>
      validateResponse<ScheduleData | null>(
        classroomScheduleSchema,
        await api.get('/classroom-rentals/schedule', {
          params: { year: month.year(), month: month.month() + 1 },
        }),
      ),
  });
  const loading = isLoading || isFetching;
  // RouteKeeper 保活页面切回时刷新排期数据
  useVisibleRefetch(['classroom-rentals', 'schedule']);

  // 按楼栋+楼层分组教室
  const groups = useMemo(() => {
    if (!data) return [];
    const map = new Map<string, any[]>();
    for (const c of data.classrooms) {
      const key = `${c.building || '其他'}${c.floor ? ` · ${c.floor}层` : ''}`;
      if (!map.has(key)) map.set(key, []);
      map.get(key)?.push(c);
    }
    return Array.from(map.entries()).map(([name, classrooms]) => ({ name, classrooms }));
  }, [data]);

  // 整体统计
  const overall = useMemo(() => {
    if (!data) return { total: 0, rented: 0, rate: 0 };
    let rented = 0;
    const total = data.classrooms.length * data.days;
    for (const cid of Object.keys(data.summary)) {
      rented += data.summary[+cid].rentedDays;
    }
    return {
      total,
      rented,
      rate: total > 0 ? Math.round((rented / total) * 100) : 0,
    };
  }, [data]);

  const showDetail = async (rentalId: number) => {
    try {
      const res: any = await api.get(`/classroom-rentals/${rentalId}`);
      setDetailModal(res);
    } catch (e: unknown) {
      message.error(getErrorMessage(e, '加载详情失败'));
    }
  };

  const handleDownloadContract = async (id: number, filename?: string) => {
    try {
      await downloadBlob(`/classroom-rentals/${id}/contract`, filename || `contract-${id}.pdf`);
    } catch {
      // downloadBlob already shows an error via throw
    }
  };

  return (
    <div>
      <div
        style={{
          marginBottom: 16,
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          flexWrap: 'wrap',
          gap: 8,
        }}
      >
        <Space>
          <CalendarOutlined style={{ fontSize: 20 }} />
          <h3 style={{ margin: 0 }}>教室排期总览</h3>
        </Space>
        <Space>
          <Button onClick={() => setMonth(month.subtract(1, 'month'))}>上月</Button>
          <DatePicker
            picker="month"
            value={month}
            onChange={(v) => v && setMonth(v)}
            allowClear={false}
            placeholder="选择月份"
            format="YYYY年M月"
          />
          <Button onClick={() => setMonth(month.add(1, 'month'))}>下月</Button>
          <Button type="primary" onClick={() => setMonth(dayjs())}>
            回到本月
          </Button>
        </Space>
      </div>

      {isError ? (
        <QueryErrorState
          title="教室排期加载失败"
          description="请检查网络后重试。"
          onRetry={() => void refetch()}
        />
      ) : (
        <>
          {/* 统计卡片 */}
          <Row gutter={[16, 16]} style={{ marginBottom: 16 }}>
            <Col xs={12} sm={6}>
              <Card size="small">
                <Statistic title="教室总数" value={data?.classrooms.length || 0} />
              </Card>
            </Col>
            <Col xs={12} sm={6}>
              <Card size="small">
                <Statistic title="本月天数" value={data?.days || 0} />
              </Card>
            </Col>
            <Col xs={12} sm={6}>
              <Card size="small">
                <Statistic title="总占用天数" value={overall.rented} suffix={`/${overall.total}`} />
              </Card>
            </Col>
            <Col xs={12} sm={6}>
              <Card size="small">
                <Statistic
                  title="整体占用率"
                  value={overall.rate}
                  suffix="%"
                  styles={{
                    value: {
                      color: overall.rate > 70 ? '#cf1322' : overall.rate > 40 ? '#fa8c16' : '#3f8600',
                    },
                  }}
                />
              </Card>
            </Col>
          </Row>

          {/* 图例 */}
          {data && (
            <Card size="small" style={{ marginBottom: 16 }} title="图例">
              <Space wrap>
                <Tag color="#52c41a">内部排课</Tag>
                {data.organizations.map((t) => (
                  <Tag
                    key={t.id}
                    color={t.color}
                    style={{ background: t.color, color: '#fff', borderColor: t.color }}
                  >
                    {t.name} (租赁)
                  </Tag>
                ))}
                <Tag color="#d9d9d9" style={{ color: '#999' }}>
                  空闲
                </Tag>
              </Space>
            </Card>
          )}

          <Spin spinning={loading}>
            {!data || data.classrooms.length === 0 ? (
              <Empty description="暂无教室数据" />
            ) : (
              <div style={{ overflowX: 'auto' }}>
                {groups.map((group) => (
                  <Card
                    key={group.name}
                    size="small"
                    title={group.name}
                    style={{ marginBottom: 12 }}
                    styles={{ body: { padding: 0 } }}
                  >
                    <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                      <thead>
                        <tr style={{ background: '#fafafa' }}>
                          <th
                            style={{
                              position: 'sticky',
                              left: 0,
                              background: '#fafafa',
                              zIndex: 2,
                              padding: '8px',
                              border: '1px solid #f0f0f0',
                              minWidth: 120,
                              textAlign: 'left',
                            }}
                          >
                            教室
                          </th>
                          <th style={{ padding: '8px 6px', border: '1px solid #f0f0f0', minWidth: 60 }}>
                            类型
                          </th>
                          <th style={{ padding: '8px 6px', border: '1px solid #f0f0f0', minWidth: 70 }}>
                            占用率
                          </th>
                          {Array.from({ length: data.days }, (_, i) => i + 1).map((d) => (
                            <th
                              key={d}
                              style={{
                                padding: '8px 4px',
                                border: '1px solid #f0f0f0',
                                minWidth: 26,
                                textAlign: 'center',
                              }}
                            >
                              {d}
                            </th>
                          ))}
                        </tr>
                      </thead>
                      <tbody>
                        {group.classrooms.map((c) => {
                          const sum = data.summary[c.id] || {
                            rentedDays: 0,
                            totalDays: data.days,
                            occupancyRate: 0,
                          };
                          return (
                            <tr key={c.id}>
                              <td
                                style={{
                                  position: 'sticky',
                                  left: 0,
                                  background: '#fff',
                                  zIndex: 1,
                                  padding: '6px 8px',
                                  border: '1px solid #f0f0f0',
                                  fontWeight: 500,
                                }}
                              >
                                {c.name}
                              </td>
                              <td
                                style={{
                                  padding: '6px',
                                  border: '1px solid #f0f0f0',
                                  textAlign: 'center',
                                }}
                              >
                                {c.roomType}
                              </td>
                              <td
                                style={{
                                  padding: '6px',
                                  border: '1px solid #f0f0f0',
                                  textAlign: 'center',
                                  color:
                                    sum.occupancyRate > 0.7
                                      ? '#cf1322'
                                      : sum.occupancyRate > 0.4
                                        ? '#fa8c16'
                                        : '#3f8600',
                                }}
                              >
                                {Math.round(sum.occupancyRate * 100)}%
                              </td>
                              {Array.from({ length: data.days }, (_, i) => i + 1).map((d) => {
                                const cell = data.matrix[c.id]?.[d];
                                const isInternal = cell?.scheduleType === 'INTERNAL';
                                const isRental = cell?.scheduleType === 'RENTAL';
                                return (
                                  <td
                                    key={d}
                                    onClick={() => {
                                      if (isRental) showDetail(cell.rentalId);
                                    }}
                                    style={{
                                      padding: 0,
                                      border: '1px solid #f0f0f0',
                                      background: cell?.color || '#fff',
                                      height: 26,
                                      cursor: isRental ? 'pointer' : 'default',
                                      textAlign: 'center',
                                    }}
                                  >
                                    {cell && (
                                      <Tooltip
                                        title={
                                          isInternal
                                            ? `${cell.className} · ${cell.subject}\n${cell.teacherName} · ${cell.startTime}-${cell.endTime}`
                                            : `${cell.organizationName}${cell.hasContract ? ' · 有合同' : ''}`
                                        }
                                      >
                                        <span style={{ color: '#fff', fontSize: 10, fontWeight: 600 }}>
                                          {isInternal ? (
                                            <ReadOutlined style={{ fontSize: 12 }} />
                                          ) : cell.hasContract ? (
                                            <FileTextOutlined style={{ fontSize: 12 }} />
                                          ) : (
                                            ''
                                          )}
                                        </span>
                                      </Tooltip>
                                    )}
                                  </td>
                                );
                              })}
                            </tr>
                          );
                        })}
                      </tbody>
                    </table>
                  </Card>
                ))}
              </div>
            )}
          </Spin>
        </>
      )}

      <Modal
        title="租赁详情"
        open={!!detailModal}
        onCancel={() => setDetailModal(null)}
        footer={null}
        width={500}
      >
        {detailModal && (
          <div style={{ lineHeight: 2 }}>
            <div>
              <strong>教室：</strong>
              {detailModal.classroom?.building} · {detailModal.classroom?.name}（
              {detailModal.classroom?.roomType}）
            </div>
            <div>
              <strong>承租机构：</strong>
              <Tag
                color={detailModal.lesseeOrganization?.color}
                style={{
                  background: detailModal.lesseeOrganization?.color,
                  color: '#fff',
                  borderColor: detailModal.lesseeOrganization?.color,
                }}
              >
                {detailModal.lesseeOrganization?.name}
              </Tag>
            </div>
            <div>
              <strong>联系人：</strong>
              {detailModal.lesseeOrganization?.contactName || '-'}{' '}
              {detailModal.lesseeOrganization?.phone || ''}
            </div>
            <div>
              <strong>起止日期：</strong>
              {detailModal.startDate} ~ {detailModal.endDate}（
              {dayjs(detailModal.endDate).diff(dayjs(detailModal.startDate), 'day') + 1}天）
            </div>
            {detailModal.dailyRate != null && (
              <div>
                <strong>日租金：</strong>¥{detailModal.dailyRate}
              </div>
            )}
            {detailModal.totalAmount != null && (
              <div>
                <strong>合同总额：</strong>¥{detailModal.totalAmount}
              </div>
            )}
            {detailModal.notes && (
              <div>
                <strong>备注：</strong>
                {detailModal.notes}
              </div>
            )}
            <div style={{ marginTop: 12 }}>
              <strong>合同文件：</strong>
              {detailModal.contractPath ? (
                <Button
                  type="link"
                  icon={<FileTextOutlined />}
                  onClick={() =>
                    handleDownloadContract(detailModal.id, detailModal.contractOriginalName)
                  }
                >
                  {detailModal.contractOriginalName || '下载'}
                </Button>
              ) : (
                '未上传'
              )}
            </div>
          </div>
        )}
      </Modal>
    </div>
  );
};

export default ClassroomSchedulePage;
