import {
  Body,
  Controller,
  Get,
  HttpStatus,
  Param,
  Patch,
  Post,
  Query,
  Req,
  Res,
  UseGuards,
  UsePipes,
} from '@nestjs/common';
import { Request, Response } from 'express';
import { CurrentUser } from '../../common/decorators/current-user.decorator';
import { ZodValidationPipe } from '../../common/pipes/zod-validation.pipe';
import { JwtAuthGuard } from '../owner/guards/jwt.guard';
import {
  addEquipmentReturnDto,
  addEquipmentReturnSchema,
  calculateFinalSettlementDto,
  calculateFinalSettlementSchema,
  createExitInterviewTemplateDto,
  createExitInterviewTemplateSchema,
  createOffboardingCaseDto,
  createOffboardingCaseSchema,
  createOffboardingTaskDto,
  createOffboardingTaskSchema,
  createOffboardingTemplateDto,
  createOffboardingTemplateSchema,
  filterOffboardingCaseDto,
  filterOffboardingCaseSchema,
  submitExitInterviewDto,
  submitExitInterviewSchema,
  updateEquipmentReturnDto,
  updateEquipmentReturnSchema,
  updateOffboardingCaseDto,
  updateOffboardingCaseSchema,
  updateOffboardingTaskDto,
  updateOffboardingTaskSchema,
} from './offboarding.dto';
import { OffboardingService } from './offboarding.service';

@Controller('offboarding')
export class OffboardingController {
  constructor(private readonly service: OffboardingService) {}

  // -------------------------------------------------------------
  // TEMPLATES
  // -------------------------------------------------------------

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(createOffboardingTemplateSchema))
  @Post('templates')
  async createTemplate(
    @Body() data: createOffboardingTemplateDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.createTemplate(data, owner_id);
    return res.status(HttpStatus.CREATED).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('templates')
  async getTemplates(
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.getTemplates(owner_id);
    return res.status(HttpStatus.OK).json({
      data: result,
      status: HttpStatus.OK,
      message: 'Templates retrieved successfully',
    });
  }

  @UseGuards(JwtAuthGuard)
  @Get('templates/:id')
  async getTemplateById(
    @Param('id') id: string,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.getTemplateById(id, owner_id);
    return res.status(HttpStatus.OK).json({
      data: result,
      status: HttpStatus.OK,
      message: 'Template retrieved successfully',
    });
  }

  // -------------------------------------------------------------
  // CASES
  // -------------------------------------------------------------

  @UseGuards(JwtAuthGuard)
  @Get('stats')
  async getDashboardStats(
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.getDashboardStats(owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('analytics/turnover')
  async getTurnoverAnalytics(
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.getTurnoverAnalytics(owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(createOffboardingCaseSchema))
  @Post()
  async createCase(
    @Body() data: createOffboardingCaseDto,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const initiatedById = (req.user as any)?.sub || (req.user as any)?.id;
    const result = await this.service.createCase(data, owner_id, initiatedById);
    return res.status(HttpStatus.CREATED).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(filterOffboardingCaseSchema))
  @Get('filter')
  async getCasesByFilter(
    @Query() query: filterOffboardingCaseDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.getCasesByFilter(query, owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get(':id')
  async getCaseById(
    @Param('id') id: string,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.getCaseById(id, owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updateOffboardingCaseSchema))
  @Patch(':id')
  async updateCase(
    @Param('id') id: string,
    @Body() data: updateOffboardingCaseDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.updateCase(id, data, owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  // -------------------------------------------------------------
  // TASKS
  // -------------------------------------------------------------

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(createOffboardingTaskSchema))
  @Post(':id/tasks')
  async addTask(
    @Param('id') caseId: string,
    @Body() data: createOffboardingTaskDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.addTask(caseId, data, owner_id);
    return res.status(HttpStatus.CREATED).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updateOffboardingTaskSchema))
  @Patch('tasks/:taskId')
  async updateTask(
    @Param('taskId') taskId: string,
    @Body() data: updateOffboardingTaskDto,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const memberId = (req.user as any)?.sub || (req.user as any)?.id;
    const result = await this.service.updateTask(taskId, data, owner_id, memberId);
    return res.status(HttpStatus.OK).json(result);
  }

  // -------------------------------------------------------------
  // EQUIPMENT RETURN
  // -------------------------------------------------------------

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(addEquipmentReturnSchema))
  @Post(':id/equipment')
  async addEquipmentReturn(
    @Param('id') caseId: string,
    @Body() data: addEquipmentReturnDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.addEquipmentReturn(caseId, data, owner_id);
    return res.status(HttpStatus.CREATED).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(updateEquipmentReturnSchema))
  @Patch('equipment/:returnId')
  async updateEquipmentReturn(
    @Param('returnId') returnId: string,
    @Body() data: updateEquipmentReturnDto,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const receiverId = (req.user as any)?.sub || (req.user as any)?.id;
    const result = await this.service.updateEquipmentReturn(returnId, data, owner_id, receiverId);
    return res.status(HttpStatus.OK).json(result);
  }

  // -------------------------------------------------------------
  // EXIT INTERVIEWS
  // -------------------------------------------------------------

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(createExitInterviewTemplateSchema))
  @Post('exit-templates')
  async createExitTemplate(
    @Body() data: createExitInterviewTemplateDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.createExitTemplate(data, owner_id);
    return res.status(HttpStatus.CREATED).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Get('exit-templates')
  async getExitTemplates(
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.getExitTemplates(owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(submitExitInterviewSchema))
  @Post(':id/exit-interview')
  async submitExitInterview(
    @Param('id') caseId: string,
    @Body() data: submitExitInterviewDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.submitExitInterview(caseId, data, owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  // -------------------------------------------------------------
  // FINAL SETTLEMENT
  // -------------------------------------------------------------

  @UseGuards(JwtAuthGuard)
  @UsePipes(new ZodValidationPipe(calculateFinalSettlementSchema))
  @Post(':id/final-settlement/calculate')
  async calculateFinalSettlement(
    @Param('id') caseId: string,
    @Body() data: calculateFinalSettlementDto,
    @CurrentUser() owner_id: string,
    @Res() res: Response,
  ) {
    const result = await this.service.calculateFinalSettlement(caseId, data, owner_id);
    return res.status(HttpStatus.OK).json(result);
  }

  @UseGuards(JwtAuthGuard)
  @Post('final-settlement/:settlementId/approve')
  async approveFinalSettlement(
    @Param('settlementId') settlementId: string,
    @CurrentUser() owner_id: string,
    @Req() req: Request,
    @Res() res: Response,
  ) {
    const approverId = (req.user as any)?.sub || (req.user as any)?.id;
    const result = await this.service.approveFinalSettlement(settlementId, owner_id, approverId);
    return res.status(HttpStatus.OK).json(result);
  }
}
