import { Injectable } from '@nestjs/common';
import { Types } from 'mongoose';
import { ListBuildSitesResponse } from './dto/list-build-sites.response';
import { CreateBuildSitesInput } from './dto/create-build-sites.input';
import { UpdateBuildSitesInput } from './dto/update-build-sites.input';
import { InjectModel } from '@nestjs/mongoose';
import { BuildSites, BuildSiteDocument } from '@/models/build-site.model';
import { Model } from 'mongoose';
import { Build, BuildDocument } from '@/models/build.model';

@Injectable()
export class BuildSitesService {

    constructor(@InjectModel(BuildSites.name) private readonly buildSitesModel: Model<BuildSiteDocument>) { }

    async findAll(projection: any, skip: number, limit: number, sort?: Record<string, 1 | -1>, filters?: Record<string, any>): Promise<ListBuildSitesResponse> {
        const query: any = {}; if (filters && Object.keys(filters).length > 0) { Object.assign(query, filters) };
        const totalCount = await this.buildSitesModel.countDocuments(query).exec();
        const data = await this.buildSitesModel.find(query, projection, { lean: true }).skip(skip).limit(limit).sort(sort).exec();
        return { data, totalCount };
    }

    async findById(id: Types.ObjectId, projection?: any): Promise<BuildSiteDocument | null> {
        return this.buildSitesModel.findById(id, projection, { lean: false }).populate({ path: 'buildSites', select: projection?.buildSites }).exec();
    }

    async create(input: CreateBuildSitesInput): Promise<BuildSiteDocument> {

        const buildSite = new this.buildSitesModel(input); return buildSite.save()
    }

    async update(uuid: string, input: UpdateBuildSitesInput): Promise<BuildSiteDocument> { const buildSite = await this.buildSitesModel.findOne({ uuid }); if (!buildSite) { throw new Error('BuildSite not found') }; buildSite.set(input); return buildSite.save() }

    async delete(uuid: string): Promise<boolean> { const buildSite = await this.buildSitesModel.deleteMany({ uuid }); return buildSite.deletedCount > 0 }

    buildProjection(fields: Record<string, any>): any {
        const projection: any = {};
        for (const key in fields) {
            if (key === 'buildSites' && typeof fields[key] === 'object') { for (const subField of Object.keys(fields[key])) { projection[`buildSites.${subField}`] = 1 } }
            else { projection[key] = 1 }
        }; return projection;
    }

}
