import {
  Injectable,
  NotFoundException,
  ForbiddenException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Room } from '@/entities/room.entity';
import { RoomCalendar } from '@/entities/room-calendar.entity';
import { CreateRoomDto, UpdateRoomDto, QueryRoomDto } from './dto/room.dto';

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

  async create(merchantId: number, dto: CreateRoomDto) {
    const room = this.roomRepo.create({ merchantId, ...dto, auditStatus: 'pending' });
    return this.roomRepo.save(room);
  }

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

  async findByIdAndMerchant(id: number, merchantId: number) {
    const room = await this.findById(id);
    if (Number(room.merchantId) !== Number(merchantId)) {
      throw new ForbiddenException('无权操作此房源');
    }
    return room;
  }

  async update(id: number, merchantId: number, dto: UpdateRoomDto) {
    const room = await this.findById(id);
    if (Number(room.merchantId) !== Number(merchantId)) {
      throw new ForbiddenException('无权操作此房源');
    }
    // 审核通过或拒绝后修改，需要重新审核
    if (room.auditStatus === 'approved' || room.auditStatus === 'rejected') {
      await this.roomRepo.update(id, { ...dto, auditStatus: 'pending', auditRejectReason: undefined });
    } else {
      await this.roomRepo.update(id, dto);
    }
    return this.findById(id);
  }

  async remove(id: number, merchantId: number) {
    const room = await this.findById(id);
    if (Number(room.merchantId) !== Number(merchantId)) {
      throw new ForbiddenException('无权操作此房源');
    }
    await this.roomRepo.update(id, { status: 'off_sale' });
    return { message: '房源已下架' };
  }

  async findByMerchant(merchantId: number, query: QueryRoomDto) {
    const { page = 1, pageSize = 10, status } = query;
    const safeMerchantId = Number(merchantId);
    const safePage = Number(page) || 1;
    const safePageSize = Number(pageSize) || 10;
    if (isNaN(safeMerchantId)) {
      return { list: [], total: 0, page: safePage, pageSize: safePageSize, totalPages: 0 };
    }
    const qb = this.roomRepo
      .createQueryBuilder('r')
      .where('r.merchant_id = :merchantId', { merchantId: safeMerchantId });

    if (status) {
      qb.andWhere('r.status = :status', { status });
    }

    qb.orderBy('r.createdAt', 'DESC');
    qb.skip((safePage - 1) * safePageSize).take(safePageSize);

    const [list, total] = await qb.getManyAndCount();
    return {
      list,
      total,
      page: safePage,
      pageSize: safePageSize,
      totalPages: Math.ceil(total / safePageSize),
    };
  }
}
