import {
  Controller,
  Get,
  Post,
  Body,
  Put,
  Param,
  Delete,
  Query,
  Req,
  Patch,
  UseGuards,
  Res,
} from "@nestjs/common"
import { PayrollService } from "./payroll.service"
import { CreatePayrollCycleDto } from "./dto/create-payroll-cycle.dto"
import { UpdatePayrollCycleDto } from "./dto/update-payroll-cycle.dto"
import {
  ProcessPayrollDto,
  EmployeeSalarySlipsDto,
} from "./dto/process-payroll.dto"
import { PayrollFiltersDto } from "./dto/payroll-filters.dto"
import { ProcessPayrollFiltersDto } from "./dto/process-payroll-filters.dto"
import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"
import { AuthGuardMiddleware } from "../../middleware/auth-guard.middleware"
import { Response } from "express"

@Controller("payroll")
@ApiBearerAuth("access-token")
@ApiTags("Payroll Management")
@UseGuards(AuthGuardMiddleware)
export class PayrollController {
  constructor(private readonly payrollService: PayrollService) {}

  @Post("cycles")
  createPayrollCycle(
    @Body() createPayrollCycleDto: CreatePayrollCycleDto,
    @Req() request: Request,
  ) {
    return this.payrollService.createPayrollCycle(
      createPayrollCycleDto,
      request.headers["authorization"],
    )
  }

  @Get("cycles")
  findAllPayrollCycles(
    @Query() query: PayrollFiltersDto,
    @Req() request: Request,
  ) {
    return this.payrollService.findAllPayrollCycles(
      query,
      request.headers["authorization"],
    )
  }

  @Get("cycles/:id")
  findOnePayrollCycle(@Param("id") id: string) {
    return this.payrollService.findOnePayrollCycle(+id)
  }

  @Put("cycles/:id")
  updatePayrollCycle(
    @Param("id") id: string,
    @Body() updatePayrollCycleDto: UpdatePayrollCycleDto,
    @Req() request: Request,
  ) {
    return this.payrollService.updatePayrollCycle(
      +id,
      updatePayrollCycleDto,
      request.headers["authorization"],
    )
  }

  @Delete("cycles/:id")
  removePayrollCycle(@Param("id") id: string, @Req() request: Request) {
    return this.payrollService.removePayrollCycle(
      +id,
      request.headers["authorization"],
    )
  }

  @Post("process")
  processPayroll(
    @Body() processPayrollDto: ProcessPayrollDto,
    @Req() request: Request,
  ) {
    return this.payrollService.processPayroll(
      processPayrollDto,
      request.headers["authorization"],
    )
  }

  @Get("cycles/:id/entries")
  getProcessPayrollData(
    @Param("id") id: string,
    @Query() query: ProcessPayrollFiltersDto,
    @Req() request: Request,
  ) {
    return this.payrollService.getProcessPayrollData(
      +id,
      query,
      request.headers["authorization"],
    )
  }

  @Patch("cycles/:id/finalize")
  finalizePayroll(@Param("id") id: string, @Req() request: Request) {
    return this.payrollService.finalizePayroll(
      +id,
      request.headers["authorization"],
    )
  }

  @Put("entries/:id/attendance")
  updatePayrollAttendance(
    @Param("id") id: string,
    @Body()
    body: {
      employee_id?: number
      payroll_cycle_id?: number
      working_days?: number
      present_days?: number
      paid_leaves?: number
      unpaid_leaves?: number
    },
    @Req() request: Request,
  ) {
    return this.payrollService.updatePayrollAttendance(
      +id,
      body,
      request.headers["authorization"],
    )
  }

  @Get("salary-slip/:payroll_entry_id")
  getSalarySlip(
    @Param("payroll_entry_id") payrollEntryId: string,
    @Req() request: Request,
  ) {
    return this.payrollService.getSalarySlip(
      +payrollEntryId,
      request.headers["authorization"],
    )
  }

  @Get("employee/salary-slips")
  getEmployeeSalarySlips(
    @Query() query: EmployeeSalarySlipsDto,
    @Req() request: Request,
  ) {
    return this.payrollService.getEmployeeSalarySlips(
      query,
      request.headers["authorization"],
    )
  }

  @Get("export/salary-slip/:payroll_entry_id/pdf")
  async exportSalarySlipPDF(
    @Param("payroll_entry_id") payrollEntryId: string,
    @Req() request: Request,
    @Res() res: Response,
  ) {
    return this.payrollService.exportSalarySlipPDF(
      +payrollEntryId,
      request.headers["authorization"],
      res,
    )
  }

  @Get("export/entries/:payroll_cycle_id")
  async exportPayrollEntries(
    @Param("payroll_cycle_id") payrollCycleId: string,
    @Req() request: Request,
    @Res() res: Response,
  ) {
    return this.payrollService.exportPayrollEntries(
      +payrollCycleId,
      request.headers["authorization"],
      res,
    )
  }
}
