import { Injectable, NotFoundException } from '@nestjs/common';
import { PrismaService } from '../../prisma/prisma.service';
import { CreateRoomDto } from './dto/create-room.dto';
import { UpdateRoomDto } from './dto/update-room.dto';
import { FindRoomsDto } from './dto/find-rooms.dto';
import { Prisma } from '@prisma/client';

export interface PaginatedResult<T> {
  data: T[];
  nextCursor: string | null;
  hasMore: boolean;
}

@Injectable()
export class RoomsService {
  constructor(private readonly prisma: PrismaService) {}

  async findAll(
    clubId: string,
    params: FindRoomsDto,
  ): Promise<PaginatedResult<any>> {
    const { cursor, limit = 20, search, isActive } = params;

    const where: Prisma.RoomWhereInput = {
      clubId,
      ...(search
        ? { name: { contains: search, mode: 'insensitive' as const } }
        : {}),
      ...(isActive !== undefined ? { isActive } : {}),
    };

    const items = await this.prisma.room.findMany({
      where,
      take: limit + 1,
      ...(cursor ? { cursor: { id: cursor }, skip: 1 } : {}),
      orderBy: { name: 'asc' },
    });

    const hasMore = items.length > limit;
    const data = hasMore ? items.slice(0, -1) : items;

    return {
      data,
      nextCursor: hasMore ? data[data.length - 1].id : null,
      hasMore,
    };
  }

  async findById(clubId: string, id: string) {
    const room = await this.prisma.room.findFirst({
      where: { id, clubId },
    });

    if (!room) {
      throw new NotFoundException(`Room with id ${id} not found`);
    }
    return room;
  }

  async create(clubId: string, dto: CreateRoomDto) {
    return this.prisma.room.create({
      data: {
        clubId,
        name: dto.name,
        capacity: dto.capacity,
        description: dto.description,
        isActive: dto.isActive ?? true,
      },
    });
  }

  async update(clubId: string, id: string, dto: UpdateRoomDto) {
    await this.ensureExists(clubId, id);

    return this.prisma.room.update({
      where: { id },
      data: {
        ...(dto.name !== undefined ? { name: dto.name } : {}),
        ...(dto.capacity !== undefined ? { capacity: dto.capacity } : {}),
        ...(dto.description !== undefined
          ? { description: dto.description }
          : {}),
        ...(dto.isActive !== undefined ? { isActive: dto.isActive } : {}),
      },
    });
  }

  async remove(clubId: string, id: string) {
    await this.ensureExists(clubId, id);
    await this.prisma.room.delete({ where: { id } });
  }

  private async ensureExists(clubId: string, id: string): Promise<void> {
    const count = await this.prisma.room.count({ where: { id, clubId } });
    if (count === 0) {
      throw new NotFoundException(`Room with id ${id} not found`);
    }
  }
}
