import React, { useEffect, useState, useCallback } from 'react';
import {
  Row,
  Col,
  Card,
  Tag,
  Select,
  Statistic,
  Modal,
  Spin,
  Badge,
  Tooltip,
  DatePicker,
  Alert,
  Button,
  Switch,
  Space,
} from 'antd';
import {
  HomeOutlined,
  UserOutlined,
  CalendarOutlined,
  BankOutlined,
  HistoryOutlined,
  ShopOutlined,
  CheckCircleOutlined,
  SaveOutlined,
} from '@ant-design/icons';
import dayjs, { Dayjs } from 'dayjs';
import api from '../../api';
import { message } from '../../ui/app-message';
import PermissionButton from '../../components/PermissionButton';
import { usePermission } from '../../hooks/usePermission';
import { getInitialPresentOccupancyIds, togglePresentOccupancy } from './inspection-state';

function getCardStyle(room: any): React.CSSProperties {
  let base: React.CSSProperties;
  if (room.status === 'maintenance') base = { background: '#f5f5f5', borderColor: '#d9d9d9' };
  else if (room.currentCount === 0) base = { background: '#f6ffed', borderColor: '#b7eb8f' };
  else if (room.currentCount >= room.capacity)
    base = { background: '#fff2f0', borderColor: '#ffccc7' };
  else base = { background: '#e6f4ff', borderColor: '#91caff' };
  if (room.organizationColor) {
    return {
      ...base,
      background: `color-mix(in srgb, ${room.organizationColor} 15%, ${base.background || '#fff'} 85%)`,
    };
  }
  return base;
}

function getStatusLabel(room: any) {
  if (room.status === 'maintenance') return <Tag color="default">维修中</Tag>;
  if (room.currentCount === 0) return <Tag color="success">空闲</Tag>;
  if (room.currentCount >= room.capacity) return <Tag color="error">满员</Tag>;
  return <Tag color="processing">部分入住</Tag>;
}

function getOrganizationTags(occupants: any[]) {
  const organizationList = [
    ...new Map(
      occupants
        .filter((o: any) => o.organizationName)
        .map((o: any) => [
          o.organizationId,
          { name: o.organizationName, color: o.organizationColor },
        ]),
    ).values(),
  ] as { name: string; color: string | null }[];
  if (organizationList.length === 0) return null;
  return (
    <div className="room-card-tag-wrapper" style={{ marginBottom: 6 }}>
      {organizationList.map((t) => (
        <Tag
          key={t.name}
          color={t.color || 'gold'}
          style={{ fontSize: 12, marginBottom: 4, maxWidth: '100%' }}
          icon={<ShopOutlined />}
        >
          {t.name}
        </Tag>
      ))}
    </div>
  );
}

const RoomVisualPage: React.FC = () => {
  const [data, setData] = useState<any>(null);
  const [loading, setLoading] = useState(true);
  const [selectedBuilding, setSelectedBuilding] = useState<string>('all');
  const [selectedOrganization, setSelectedOrganization] = useState<number | 'all'>('all');
  const [detailRoom, setDetailRoom] = useState<any>(null);
  const [asOf, setAsOf] = useState<Dayjs | null>(null);
  const [presentOccupancyIds, setPresentOccupancyIds] = useState<number[]>([]);
  const [inspectionSaving, setInspectionSaving] = useState(false);
  const { hasPermission } = usePermission();

  const isHistorical = !!asOf && !asOf.isSame(dayjs(), 'day');

  const fetchData = useCallback(async () => {
    setLoading(true);
    try {
      const params = isHistorical ? { asOf: asOf!.format('YYYY-MM-DD') } : undefined;
      const res: any = await api.get('/rooms/visual', { params });
      setData(res);
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '加载失败，请稍后重试');
    }
    setLoading(false);
  }, [isHistorical, asOf]);

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

  useEffect(() => {
    if (!detailRoom) {
      setPresentOccupancyIds([]);
      return;
    }
    setPresentOccupancyIds(
      getInitialPresentOccupancyIds(
        detailRoom.occupants || [],
        detailRoom.inspection?.submitted === true,
      ),
    );
  }, [detailRoom]);

  const inspectionDate = (asOf || dayjs()).format('YYYY-MM-DD');

  const submitInspection = async () => {
    if (!detailRoom || isHistorical) return;
    setInspectionSaving(true);
    try {
      await api.put(`/rooms/${detailRoom.id}/inspections/${inspectionDate}`, {
        presentOccupancyIds,
      });
      message.success(detailRoom.inspection?.submitted ? '查寝记录已更新' : '查寝已提交');
      const params = isHistorical ? { asOf: inspectionDate } : undefined;
      const res: any = await api.get('/rooms/visual', { params });
      setData(res);
      const updatedRoom = res.rooms.find((room: any) => room.id === detailRoom.id);
      if (updatedRoom) setDetailRoom(updatedRoom);
    } catch (e: unknown) {
      const err = e as { message?: string };
      message.error(err?.message || '查寝提交失败');
    } finally {
      setInspectionSaving(false);
    }
  };

  if (!data) return <Spin size="large" style={{ display: 'block', margin: '100px auto' }} />;

  const rooms = data.rooms.filter((r: any) => {
    if (selectedBuilding !== 'all' && r.building !== selectedBuilding) return false;
    if (selectedOrganization !== 'all' && !(r.organizationIds || []).includes(selectedOrganization))
      return false;
    return true;
  });

  const totalRooms = rooms.length;
  const emptyRooms = rooms.filter(
    (r: any) => r.currentCount === 0 && r.status !== 'maintenance',
  ).length;
  const totalBeds = rooms.reduce((sum: number, r: any) => sum + (r.totalBeds || 0), 0);
  const occupiedBeds = rooms.reduce((sum: number, r: any) => sum + (r.occupiedBeds || 0), 0);
  const availableBedsCount = totalBeds - occupiedBeds;
  const fullRooms = rooms.filter((r: any) => r.currentCount >= r.capacity).length;

  /* getCardStyle, getStatusLabel, getOrganizationTags are now standalone functions outside the component */

  return (
    <div>
      <div
        style={{
          marginBottom: 16,
          display: 'flex',
          justifyContent: 'space-between',
          alignItems: 'center',
          flexWrap: 'wrap',
          gap: 12,
        }}
      >
        <h2 style={{ margin: 0 }}>宿舍总览</h2>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
          <DatePicker
            value={asOf}
            onChange={setAsOf}
            allowClear
            placeholder="查看历史日期"
            suffixIcon={<HistoryOutlined />}
            disabledDate={(d) => d && d.isAfter(dayjs(), 'day')}
            style={{ width: 180 }}
          />
          <Select
            value={selectedBuilding}
            onChange={setSelectedBuilding}
            style={{ width: 160 }}
            options={[
              { value: 'all', label: '全部楼栋' },
              ...data.buildings.map((b: string) => ({ value: b, label: b })),
            ]}
          />
          <Select
            value={selectedOrganization}
            onChange={setSelectedOrganization}
            style={{ width: 180 }}
            options={[
              { value: 'all', label: '全部机构' },
              ...(data.organizations || []).map((t: any) => ({
                value: t.id,
                label: (
                  <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                    {t.color && (
                      <span
                        style={{
                          width: 8,
                          height: 8,
                          borderRadius: '50%',
                          backgroundColor: t.color,
                          display: 'inline-block',
                        }}
                      />
                    )}
                    {t.name}
                  </span>
                ),
              })),
            ]}
          />
        </div>
      </div>

      {isHistorical && (
        <Alert
          type="warning"
          showIcon
          icon={<HistoryOutlined />}
          style={{ marginBottom: 16 }}
          title={`正在查看 ${asOf!.format('YYYY年M月D日')} 的历史入住情况（含当日已归档房间），非实时数据`}
          action={
            <Button size="small" type="link" onClick={() => setAsOf(null)}>
              返回今天
            </Button>
          }
        />
      )}

      {loading && <Spin style={{ display: 'block', margin: '8px auto 16px' }} />}

      {/* 统计栏 */}
      <Row gutter={[12, 12]} style={{ marginBottom: 20 }}>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic title="宿舍总数" value={totalRooms} prefix={<HomeOutlined />} />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic
              title="空闲房间"
              value={emptyRooms}
              styles={{ value: { color: '#34C759' } }}
            />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic
              title="可安排床位"
              value={availableBedsCount}
              styles={{ value: { color: '#007AFF' } }}
            />
          </Card>
        </Col>
        <Col xs={12} sm={6}>
          <Card size="small">
            <Statistic
              title="满员房间"
              value={fullRooms}
              styles={{ value: { color: '#FF3B30' } }}
            />
          </Card>
        </Col>
      </Row>

      {/* 房态网格 */}
      <Row gutter={[12, 12]}>
        {rooms.map((room: any) => (
          <Col xs={12} sm={8} md={6} lg={4} key={room.id}>
            <Card
              size="small"
              hoverable
              style={{
                ...getCardStyle(room),
                borderRadius: 12,
                borderWidth: 2,
                cursor: 'pointer',
                height: '100%',
              }}
              onClick={() => setDetailRoom(room)}
            >
              <div
                style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  marginBottom: 8,
                }}
              >
                <span
                  style={{
                    display: 'flex',
                    alignItems: 'center',
                    gap: 6,
                    fontSize: 16,
                    fontWeight: 600,
                    color: '#1d1d1f',
                  }}
                >
                  {room.organizationColor && (
                    <span
                      style={{
                        width: 10,
                        height: 10,
                        borderRadius: '50%',
                        backgroundColor: room.organizationColor,
                        display: 'inline-block',
                        flexShrink: 0,
                      }}
                    />
                  )}
                  {room.roomNumber}
                </span>
                {getStatusLabel(room)}
              </div>
              <div style={{ color: '#86868b', fontSize: 12, marginBottom: 6 }}>
                {room.building && <span>{room.building} </span>}
                {room.floor && <span>{room.floor}F</span>}
              </div>
              {room.totalBeds > 0 && (
                <div
                  style={{
                    fontSize: 12,
                    color: room.occupiedBeds >= room.totalBeds ? '#FF3B30' : '#34C759',
                    marginBottom: 6,
                  }}
                >
                  床位: {room.occupiedBeds}/{room.totalBeds}
                </div>
              )}
              <div style={{ display: 'flex', alignItems: 'center', gap: 4, marginBottom: 8 }}>
                <Badge
                  count={`${room.currentCount}/${room.capacity}`}
                  showZero
                  style={{
                    backgroundColor:
                      room.currentCount >= room.capacity
                        ? '#FF3B30'
                        : room.currentCount > 0
                          ? '#007AFF'
                          : '#34C759',
                    fontSize: 12,
                  }}
                />
              </div>
              {room.orgLabel && (
                <div className="room-card-tag-wrapper" style={{ marginBottom: 6 }}>
                  <Tag color="purple" style={{ fontSize: 12 }} icon={<BankOutlined />}>
                    {room.orgLabel}
                  </Tag>
                </div>
              )}
              {getOrganizationTags(room.occupants)}
              {room.occupants.length > 0 && (
                <div
                  className="room-card-tag-wrapper"
                  style={{ borderTop: '1px solid rgba(0,0,0,0.06)', paddingTop: 6 }}
                >
                  {room.occupants.slice(0, 4).map((o: any) => (
                    <Tooltip key={o.studentId} title={`入住 ${o.days} 天 (${o.checkInDate} 起)`}>
                      <Tag
                        style={{ margin: '0 4px 4px 0', fontSize: 12, maxWidth: '100%' }}
                        icon={<UserOutlined />}
                      >
                        {o.studentName}
                      </Tag>
                    </Tooltip>
                  ))}
                  {room.occupants.length > 4 && <Tag>+{room.occupants.length - 4}</Tag>}
                </div>
              )}
              {room.occupants.length > 0 && (
                <div style={{ marginTop: 4 }}>
                  {room.inspection?.submitted ? (
                    <Tag color={room.inspection.source === 'automatic' ? 'orange' : 'green'}>
                      {room.inspection.source === 'automatic' ? '自动补记' : '已查寝'}
                    </Tag>
                  ) : (
                    <Tag>未查寝</Tag>
                  )}
                </div>
              )}
            </Card>
          </Col>
        ))}
      </Row>

      {/* 详情弹窗 */}
      <Modal
        title={`宿舍 ${detailRoom?.roomNumber} 详情`}
        open={!!detailRoom}
        onCancel={() => setDetailRoom(null)}
        footer={null}
        width={500}
      >
        {detailRoom && (
          <div>
            <Row gutter={16} style={{ marginBottom: 16 }}>
              <Col span={8}>
                <Statistic title="额定人数" value={detailRoom.capacity} />
              </Col>
              <Col span={8}>
                <Statistic title="当前入住" value={detailRoom.currentCount} />
              </Col>
              <Col span={8}>
                <Statistic
                  title="剩余床位"
                  value={Math.max(0, detailRoom.capacity - detailRoom.currentCount)}
                />
              </Col>
            </Row>
            <div style={{ marginBottom: 8, fontWeight: 500 }}>
              位置：{detailRoom.building || '-'} {detailRoom.floor ? `${detailRoom.floor}F` : ''}
            </div>

            {detailRoom.organizationColor && (
              <div style={{ marginBottom: 8 }}>
                <Tag color={detailRoom.organizationColor}>
                  {detailRoom.occupants[0]?.organizationName || '机构'}
                </Tag>
              </div>
            )}
            <div style={{ marginBottom: 16 }}>{getStatusLabel(detailRoom)}</div>
            {detailRoom.occupants.length > 0 ? (
              <div>
                <div
                  style={{
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    gap: 12,
                    marginBottom: 8,
                    flexWrap: 'wrap',
                  }}
                >
                  <h4 style={{ margin: 0 }}>床位查寝</h4>
                  {detailRoom.inspection?.submitted && (
                    <Tag color={detailRoom.inspection.source === 'automatic' ? 'orange' : 'green'}>
                      {detailRoom.inspection.source === 'automatic' ? '自动补记' : '已提交'} ·{' '}
                      {detailRoom.inspection.inspectorName}
                    </Tag>
                  )}
                </div>
                {detailRoom.occupants.map((o: any) => (
                  <Card key={o.occupancyId} size="small" style={{ marginBottom: 8, borderRadius: 8 }}>
                    <div
                      style={{
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                      }}
                    >
                      <div>
                        <UserOutlined style={{ marginRight: 6 }} />
                        <strong>{o.studentName}</strong>
                        {o.organization && (
                          <Tag color="purple" style={{ marginLeft: 6, fontSize: 12 }}>
                            {o.organization}
                          </Tag>
                        )}
                      </div>
                      {isHistorical ? (
                        <Tag
                          color={
                            o.inspectionStatus === 'present'
                              ? 'green'
                              : o.inspectionStatus === 'absent'
                                ? 'red'
                                : 'default'
                          }
                        >
                          {o.inspectionStatus === 'present'
                            ? '在寝'
                            : o.inspectionStatus === 'absent'
                              ? '缺勤'
                              : '无记录'}
                        </Tag>
                      ) : (
                        <Space size="small">
                          <span style={{ color: '#86868b', fontSize: 12 }}>
                            {presentOccupancyIds.includes(o.occupancyId) ? '在寝' : '缺勤'}
                          </span>
                          <Switch
                            checked={presentOccupancyIds.includes(o.occupancyId)}
                            disabled={!hasPermission('room:inspect')}
                            checkedChildren="在寝"
                            unCheckedChildren="缺勤"
                            onChange={(checked) =>
                              setPresentOccupancyIds((current) =>
                                togglePresentOccupancy(current, o.occupancyId, checked),
                              )
                            }
                          />
                        </Space>
                      )}
                    </div>
                    <div style={{ color: '#86868b', fontSize: 12, marginTop: 4 }}>
                      <CalendarOutlined style={{ marginRight: 4 }} />
                      床位：{o.bedNumber || '未分配'} |{' '}
                      入住：{o.checkInDate} | 计费起：{o.billingStartDate}
                      {o.supervisor && (
                        <span style={{ marginLeft: 8 }}>负责人：{o.supervisor}</span>
                      )}
                    </div>
                  </Card>
                ))}
                {!isHistorical && hasPermission('room:inspect') && (
                  <div
                    style={{
                      display: 'flex',
                      justifyContent: 'flex-end',
                      gap: 8,
                      marginTop: 16,
                      flexWrap: 'wrap',
                    }}
                  >
                    <Button
                      icon={<CheckCircleOutlined />}
                      onClick={() =>
                        setPresentOccupancyIds(
                          detailRoom.occupants.map((occupant: any) => occupant.occupancyId),
                        )
                      }
                    >
                      本宿舍一键打卡
                    </Button>
                    <PermissionButton
                      permission="room:inspect"
                      type="primary"
                      icon={<SaveOutlined />}
                      loading={inspectionSaving}
                      onClick={submitInspection}
                    >
                      提交查寝
                    </PermissionButton>
                  </div>
                )}
              </div>
            ) : (
              <div style={{ textAlign: 'center', padding: 24, color: '#86868b' }}>
                当前无住户，可安排入住
              </div>
            )}
          </div>
        )}
      </Modal>
    </div>
  );
};

export default RoomVisualPage;
