// RoomServicesModel.ts
import { Service, Room } from "entity";
import { SelectQueryBuilder } from "typeorm";
import CommonHelper from "../helpers/common";
import { OrmHelper } from "../helpers/orm";

export class RoomServicesModel {
    static async listByService(filter = {}, withDeleted = false): Promise<SelectQueryBuilder<Service>> {
        const repo = OrmHelper.DB.getRepository(Service);
        let whereAttr: string[] = [];
        let whereVal: any = {};

        if (filter && Object.keys(filter).length > 0) {
            const filterResult = CommonHelper.handleQueryFilter(filter);
            whereAttr = [...whereAttr, ...filterResult.whereAttr];
            whereVal = { ...whereVal, ...filterResult.whereVal };
        }

        let query = repo.createQueryBuilder("Service")
            .leftJoinAndSelect("Service.rooms", "Room")
            .leftJoinAndSelect("Room.department", "Department")
            .leftJoinAndSelect("Service.serviceType", "ServiceType");

        if (whereAttr.length != 0) {
            query = query.where(whereAttr.join(" and "), whereVal);
        }

        if (withDeleted) {
            query = query.withDeleted();
        }

        return query;
    }

    static async listByRoom(filter = {}, withDeleted = false): Promise<SelectQueryBuilder<Room>> {
        const repo = OrmHelper.DB.getRepository(Room);
        let whereAttr: string[] = [];
        let whereVal: any = {};

        if (filter && Object.keys(filter).length > 0) {
            const filterResult = CommonHelper.handleQueryFilter(filter, "Room");
            whereAttr = [...whereAttr, ...filterResult.whereAttr];
            whereVal = { ...whereVal, ...filterResult.whereVal };
        }

        let query = repo.createQueryBuilder("Room")
            .leftJoinAndSelect("Room.services", "Service")
            .leftJoinAndSelect("Room.department", "Department")
            .leftJoinAndSelect("Service.serviceType", "ServiceType");

        if (whereAttr.length != 0) {
            query = query.where(whereAttr.join(" and "), whereVal);
        }

        if (withDeleted) {
            query = query.withDeleted();
        }

        return query;
    }

    // Method untuk count rooms (bukan relationships)
    static async countRooms(filter = {}, withDeleted = false): Promise<number> {
        const repo = OrmHelper.DB.getRepository(Service);

        // Query untuk menghitung total unique rooms yang punya services
        let queryBuilder = repo.createQueryBuilder("Service")
            .innerJoin("Service.rooms", "Room")
            .select("COUNT(DISTINCT Room.id)", "count");

        if (filter && Object.keys(filter).length > 0) {
            const filterResult = CommonHelper.handleQueryFilter(filter);
            if (filterResult.whereAttr.length > 0) {
                queryBuilder = queryBuilder.where(filterResult.whereAttr.join(" and "), filterResult.whereVal);
            }
        }

        if (withDeleted) {
            queryBuilder = queryBuilder.withDeleted();
        }

        const result = await queryBuilder.getRawOne();
        return parseInt(result.count) || 0;
    }

    // Method untuk count services
    static async countServices(filter = {}, withDeleted = false): Promise<number> {
        const repo = OrmHelper.DB.getRepository(Room);

        // Query untuk menghitung total unique services yang punya rooms
        let queryBuilder = repo.createQueryBuilder("Room")
            .innerJoin("Room.services", "Service")
            .select("COUNT(DISTINCT Service.id)", "count");

        if (filter && Object.keys(filter).length > 0) {
            const filterResult = CommonHelper.handleQueryFilter(filter, "Room");
            if (filterResult.whereAttr.length > 0) {
                queryBuilder = queryBuilder.where(filterResult.whereAttr.join(" and "), filterResult.whereVal);
            }
        }

        if (withDeleted) {
            queryBuilder = queryBuilder.withDeleted();
        }

        const result = await queryBuilder.getRawOne();
        return parseInt(result.count) || 0;
    }
}
