import {
  Body,
  Controller,
  Get,
  HttpStatus,
  Param,
  Patch,
  Post,
  Req,
  Res,
  UseGuards,
  UsePipes,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { getPermissionContext } from '../../common/access-control/permission-request.util';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe';
import { JwtAuthGuard } from '../owner/guards/jwt.guard';
import {
  UpdateCompanyInfoDto,
  UpdateLeavePolicyDto,
  UpdateWorkScheduleDto,
  updataLeavePolicySchema,
  updateCompanyInfoSchema,
  updateWorkScheduleSchema,
  UpdateAttendanceValidationSettingsDto,
  updateAttendanceValidationSettingsSchema,
} from './configurations.dto';
import { ConfigurationsService } from './configurations.service';

@Controller('configurations')
export class ConfigurationsController {
  constructor(private readonly configurationsService: ConfigurationsService) {}

  @UseGuards(JwtAuthGuard)
  @Post('create-default')
  async createDefaultConfiguration(
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    await this.configurationsService.createDefaultConfiguration(owner_id);
    return res.status(HttpStatus.CREATED).json({
      data: null,
      message: 'Default configuration created successfully',
      status: HttpStatus.CREATED,
      details: null,
    });
  }

  @UseGuards(JwtAuthGuard)
  @Get('company-info')
  async getCompanyInfo(
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.getCompanyInfo(
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('work-schedule')
  async getWorkSchedule(
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.getWorkSchedule(
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('leave-policy')
  async getLeavePolicy(
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.getLeavePolicy(
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updateCompanyInfoSchema))
  @Patch('company-info/:id')
  async updateCompanyInfo(
    @Param('id') id: string,
    @CurrentUser() owner_id: string,
    @Body() data: UpdateCompanyInfoDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.updateCompanyInfo(
      id,
      owner_id,
      data,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updateWorkScheduleSchema))
  @Patch('work-schedule/:id')
  async updateWorkSchedule(
    @Param('id') id: string,
    @CurrentUser() owner_id: string,
    @Body() data: UpdateWorkScheduleDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.updateWorkSchedule(
      id,
      owner_id,
      data,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updataLeavePolicySchema))
  @Patch('leave-policy/:id')
  async updateLeavePolicy(
    @Param('id') id: string,
    @CurrentUser() owner_id: string,
    @Body() data: UpdateLeavePolicyDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.updateLeavePolicy(
      id,
      owner_id,
      data,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('work-day-schedules')
  async getWorkDaySchedules(
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.getWorkDaySchedules(
      owner_id,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Patch('work-day-schedules')
  async updateWorkDaySchedules(
    @CurrentUser() owner_id: string,
    @Body() body: any,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result = await this.configurationsService.updateWorkDaySchedules(
      owner_id,
      body,
      getPermissionContext(req.user as any),
    );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('attendance-validation')
  async getAttendanceValidationSettings(
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result =
      await this.configurationsService.getAttendanceValidationSettings(
        owner_id,
        getPermissionContext(req.user as any),
      );
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updateAttendanceValidationSettingsSchema))
  @Patch('attendance-validation')
  async updateAttendanceValidationSettings(
    @CurrentUser() owner_id: string,
    @Body() body: UpdateAttendanceValidationSettingsDto,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const result =
      await this.configurationsService.updateAttendanceValidationSettings(
        owner_id,
        body,
        getPermissionContext(req.user as any),
      );
    return res.status(HttpStatus.OK).json(result);
  }
}
