import { Injectable } from "@nestjs/common";
import { Result } from "src/common/errors/result-error.factory";
import { EmailToIdResolver } from "src/common/mappers/email-id.mapper";
import { PrismaPostgresService } from "prisma/postgres/prisma-postgres.service";
import { PaidTimeOFfBankHoursService } from "src/time-and-attendance/paid-time-off/paid-time-off.service";
import { PayPeriodEventService } from "src/time-and-attendance/pay-period/services/pay-period-event.service";

@Injectable()
export class ShiftsDeleteService {
    constructor(
        private readonly prisma: PrismaPostgresService,
        private readonly paidTimeOffService: PaidTimeOFfBankHoursService,
        private readonly emailResolver: EmailToIdResolver,
        private readonly payPeriodEventService: PayPeriodEventService,
    ) { }
    //_________________________________________________________________
    //                              DELETE
    //_________________________________________________________________
    //finds shifts using shit_ids
    //ajust paid-time-off banks
    //blocs deletion if approved
    async deleteShift(shift_id: number, email: string, is_from_timesheet: boolean = true): Promise<Result<number, string>> {
        try {

            //verify if email is valid or not
            const employee_id = await this.emailResolver.findIdByEmail(email);
            if (!employee_id.success) return { success: false, error: employee_id.error };

            // check if shift actually belongs to employee
            const shift = await this.prisma.shifts.findUnique({
                where: { id: shift_id },
                select: {
                    timesheet: {
                        select: {
                            employee_id: true,
                        }
                    }
                }
            });

            if (!shift || shift.timesheet.employee_id !== employee_id.data)
                return { success: false, error: 'SHIFT_NOT_FOUND'}            

            // return deletion result
            return await this.prisma.$transaction(async (tx) => {
                const shift = await tx.shifts.findUnique({
                    where: { id: shift_id },
                    select: {
                        id: true,
                        date: true,
                        start_time: true,
                        end_time: true,
                        timesheet: true,
                        is_approved: true,
                        bank_code: { select: { type: true } },
                    },
                });

                if (!shift) return { success: false, error: `SHIFT_NOT_FOUND` };
                if (shift.is_approved) return { success: false, error: 'APPROVED_SHIFT' };

                //call to ajust paid_time_off hour banks
                await this.paidTimeOffService.updatePaidTimeoffBankHoursWhenShiftDelete(
                    shift.start_time,
                    shift.end_time,
                    shift.bank_code.type,
                    shift.timesheet.employee_id
                );
                await tx.shifts.delete({ where: { id: shift_id } });

                // push to event service to notify timesheet-approval subscribers of change
                if (is_from_timesheet) {
                    this.payPeriodEventService.emit({
                        employee_email: email,
                        event_type: 'shift',
                        action: 'delete'
                    })
                }

                return { success: true, data: shift.id };
            });
        } catch (error) {
            return { success: false, error: `SHIFT_NOT_FOUND` };
        }
    }
}