import { Body, Controller, Get, Param, MessageEvent, ParseIntPipe, Patch, Sse } from "@nestjs/common";
import { PayPeriodOverviewDto } from "./dtos/overview-pay-period.dto";
import { PayPeriodsQueryService } from "./services/pay-periods-query.service";
import { PayPeriodsCommandService } from "./services/pay-periods-command.service";
import { Result } from "src/common/errors/result-error.factory";
import { ModuleAccessAllowed } from "src/common/decorators/modules-guard.decorators";
import { Modules as ModulesEnum } from "prisma/postgres/generated/prisma/client/postgres/client";
import { GetOverviewService } from "src/time-and-attendance/pay-period/services/pay-periods-build-overview.service";
import { map, Observable } from "rxjs";
import { PayPeriodEventService } from "src/time-and-attendance/pay-period/services/pay-period-event.service";

@Controller('pay-periods')
export class PayPeriodsController {

    constructor(
        private readonly queryService: PayPeriodsQueryService,
        private readonly getOverviewService: GetOverviewService,
        private readonly commandService: PayPeriodsCommandService,
        private readonly payPeriodEventService: PayPeriodEventService,
    ) { }

    @Sse("subscribe")
    sse(): Observable<MessageEvent> {
        return this.payPeriodEventService.stream().pipe(map(event => ({ data: event, })));
    }

    @Get("date/:date")
    @ModuleAccessAllowed(ModulesEnum.timesheets)
    async findByDate(@Param("date") date: string) {
        return this.queryService.findByDate(date);
    }

    @Get(":year/:periodNumber")
    @ModuleAccessAllowed(ModulesEnum.timesheets)
    async findOneByYear(
        @Param("year", ParseIntPipe) year: number,
        @Param("periodNumber", ParseIntPipe) period_no: number,
    ) {
        return this.queryService.findOneByYearPeriod(year, period_no);
    }

    @Patch("pay-period-approval")
    @ModuleAccessAllowed(ModulesEnum.timesheets_approval)
    async bulkApproval(
        @Body('email') email: string,
        @Body('timesheet_ids') timesheet_ids: number[],
        @Body('is_approved') is_approved: boolean,
    ): Promise<Result<{ shifts: number, expenses: number }, string>> {
        if (!email) return { success: false, error: 'EMAIL_REQUIRED' };
        if (!timesheet_ids || timesheet_ids.length < 1) return { success: false, error: 'TIMESHEET_ID_REQUIRED' };
        if (is_approved === null) return { success: false, error: 'APPROVAL_STATUS_REQUIRED' }
        return this.commandService.bulkApproveEmployee(email, timesheet_ids, is_approved);
    }

    @Get('overview/:year/:periodNumber')
    @ModuleAccessAllowed(ModulesEnum.timesheets_approval)
    async getOverviewByYear(
        @Param('year', ParseIntPipe) year: number,
        @Param('periodNumber', ParseIntPipe) period_no: number,
    ): Promise<Result<PayPeriodOverviewDto, string>> {
        return this.getOverviewService.getOverviewByYearPeriod(year, period_no);
    }
}
