import { Injectable, NotFoundException } from "@nestjs/common";
import { Prisma, Timesheets } from "prisma/postgres/generated/prisma/client/postgres/client";
import { PrismaPostgresService, TransactionClient } from "prisma/postgres/prisma-postgres.service";
import { BaseApprovalService } from "src/common/shared/base-approval.service";
import { timesheet_select } from "src/time-and-attendance/utils/selects.utils";




 @Injectable()
 export class TimesheetApprovalService extends BaseApprovalService<Timesheets>{
    constructor(
        prisma: PrismaPostgresService,
    ){super(prisma)}

    //_____________________________________________________________________________________________
    //                                  APPROVAL AND DELEGATE METHODS
    //_____________________________________________________________________________________________
    protected get delegate() {
        return this.prisma.timesheets;
    }

    protected delegateFor(tx: TransactionClient) {
        return tx.timesheets;
    }

    async updateApproval(id: number, is_approved: boolean): Promise<Timesheets> {
        return this.prisma.$transaction((tx) => 
            this.updateApprovalWithTransaction(tx, id, is_approved),
        );
    }

    async cascadeApprovalWithtx(tx: TransactionClient, timesheet_id: number, is_approved: boolean): Promise<Timesheets> {
        const timesheet = await this.updateApprovalWithTransaction(tx, timesheet_id, is_approved);
        await tx.shifts.updateMany({
            where: { timesheet_id: timesheet_id },
            data:  { is_approved:  is_approved  },
        });
        await tx.expenses.updateMany({
            where: { timesheet_id: timesheet_id },
            data:  { is_approved:  is_approved  },
        });
        return timesheet;
    }

    async approveTimesheetById( timesheet_id: number, is_approved: boolean){
        return this.prisma.$transaction(async (tx) => {
            const timesheet = await tx.timesheets.findUnique({
                where: { id: timesheet_id },
                select: { id: true },
            });
            if(!timesheet) throw new NotFoundException(`Timesheet with id: ${timesheet_id} not found`);
            
            await this.cascadeApprovalWithtx(tx, timesheet_id, is_approved);

            return tx.timesheets.findUnique({
                where: { id: timesheet_id },
                select: timesheet_select,
            });
        });
    }
 }