import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, LessThan, MoreThanOrEqual } from 'typeorm';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { QueryAvailableRoomsDto } from './dto/room.dto';

@Injectable()
export class RoomService {
  constructor(
    @InjectRepository(Room)
    private roomRepo: Repository<Room>,
    @InjectRepository(RoomCalendar)
    private calendarRepo: Repository<RoomCalendar>,
  ) {}

  async findById(id: number) {
    const room = await this.roomRepo.findOne({
      where: { id: Number(id) },
      relations: ['merchant'],
    });
    if (!room) throw new NotFoundException('房源不存在');
    return room;
  }

  async getRoomCalendar(roomId: number, startDate: string, endDate: string) {
    const calendar = await this.calendarRepo.find({
      where: {
        roomId: Number(roomId),
        date: MoreThanOrEqual(startDate) && LessThan(endDate),
      },
      order: { date: 'ASC' },
    });

    return calendar;
  }

  async findAvailable(query: QueryAvailableRoomsDto) {
    const {
      merchantId,
      checkIn,
      checkOut,
      roomCount = 1,
      adultCount = 1,
      childCount = 0,
      page = 1,
      pageSize = 10,
    } = query;

    const qb = this.roomRepo
      .createQueryBuilder('room')
      .where('room.status = :status', { status: 'on_sale' })
      .andWhere('room.audit_status = :auditStatus', { auditStatus: 'approved' });

    // 按商家筛选
    if (merchantId) {
      qb.andWhere('room.merchant_id = :merchantId', { merchantId });
    }

    // 按容纳人数筛选
    const totalGuests = adultCount + childCount;
    qb.andWhere('room.max_guests >= :totalGuests', { totalGuests });

    // 如果提供了日期，检查可用性
    let roomPriceMap = new Map<number, number>(); // 存储每个房间的实际价格

    if (checkIn && checkOut) {
      // 计算需要的天数
      const checkInDate = new Date(checkIn);
      const checkOutDate = new Date(checkOut);
      const daysDiff = Math.ceil((checkOutDate.getTime() - checkInDate.getTime()) / (1000 * 60 * 60 * 24));

      // 查询日历记录
      const calendarRecords = await this.calendarRepo
        .createQueryBuilder('cal')
        .where('cal.date >= :checkIn', { checkIn })
        .andWhere('cal.date < :checkOut', { checkOut })
        .andWhere('cal.status = :status', { status: 'available' })
        .getMany();

      // 按房间ID分组，检查每个房间是否在所有日期都有足够库存，并计算总价
      const roomAvailability = new Map<number, number>();
      const roomTotalPrice = new Map<number, number>();

      for (const record of calendarRecords) {
        const availableStock = record.stock - record.sold;
        if (availableStock >= roomCount) {
          const count = roomAvailability.get(record.roomId) || 0;
          roomAvailability.set(record.roomId, count + 1);

          // 累加价格
          const totalPrice = roomTotalPrice.get(record.roomId) || 0;
          roomTotalPrice.set(record.roomId, totalPrice + Number(record.price));
        }
      }

      // 筛选出在所有日期都有库存的房间
      const availableRoomIds = Array.from(roomAvailability.entries())
        .filter(([_, count]) => count >= daysDiff)
        .map(([roomId, _]) => roomId);

      if (availableRoomIds.length > 0) {
        qb.andWhere('room.id IN (:...roomIds)', { roomIds: availableRoomIds });

        // 计算每个房间的平均价格（用于显示）
        availableRoomIds.forEach(roomId => {
          const totalPrice = roomTotalPrice.get(roomId) || 0;
          roomPriceMap.set(roomId, totalPrice / daysDiff);
        });
      } else {
        // 没有可用房间，返回空结果
        return { list: [], total: 0, page, pageSize };
      }
    }

    qb.orderBy('room.created_at', 'DESC');
    qb.skip((page - 1) * pageSize).take(pageSize);

    const [list, total] = await qb.getManyAndCount();

    // 批量加载 merchant 关系
    if (list.length > 0) {
      const merchantIds = [...new Set(list.map(room => room.merchantId))];
      const merchants = await this.roomRepo.manager
        .createQueryBuilder()
        .from('merchants', 'merchant')
        .where('merchant.id IN (:...merchantIds)', { merchantIds })
        .getMany();

      const merchantMap = new Map(merchants.map(m => [m.id, m]));

      // 转换为普通对象并添加 currentPrice
      const result = list.map(room => {
        const roomData = {
          ...room,
          merchant: merchantMap.get(room.merchantId),
        };

        // 如果有日历价格，添加 currentPrice 字段
        if (roomPriceMap.has(room.id)) {
          roomData['currentPrice'] = roomPriceMap.get(room.id);
        }

        return roomData;
      });

      return { list: result, total, page, pageSize };
    }

    return { list, total, page, pageSize };
  }
}
