import { WorkflowConfigurationResponseDto } from './dto/workflow-configuration-response.dto';
import { Controller, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Res } from '@nestjs/common';
import { ApiOperation, ApiParam, ApiResponse, ApiTags } from '@nestjs/swagger';
import { Response } from 'express';
import { ResponseService } from 'src/common/response-handling/response-handler';
import { handleControllerError } from 'src/common/utils/controller-response-handling';
import { WorkflowService } from './workflow.service';
import InifniBadRequestException from 'src/common/exceptions/infini-badrequest-exception';

@ApiTags('Workflow')
@Controller('workflow')
export class WorkflowController {
  constructor(
    private readonly workflowService: WorkflowService,
    private readonly responseService: ResponseService,
  ) {}

  @Get('registration/:id/progress')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Get registration workflow progress' })
  @ApiParam({ name: 'id', type: Number })
  @ApiResponse({ status: HttpStatus.OK, description: 'Workflow progress fetched successfully' })
  async getWorkflowProgress(@Param('id', ParseIntPipe) registrationId: number, @Res() res: Response) {
    try {
      const data = await this.workflowService.getWorkflowProgress(registrationId);
      await this.responseService.success(res, 'Workflow progress fetched successfully', data, HttpStatus.OK);
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  @Get('registration/:id/current-stage')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Get registration current workflow stage' })
  @ApiParam({ name: 'id', type: Number })
  @ApiResponse({ status: HttpStatus.OK, description: 'Current workflow stage fetched successfully' })
  async getCurrentStage(@Param('id', ParseIntPipe) registrationId: number, @Res() res: Response) {
    try {
      const data = await this.workflowService.getCurrentStage(registrationId);
      await this.responseService.success(res, 'Current workflow stage fetched successfully', data, HttpStatus.OK);
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  @Get('key/:workflowKey')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Get workflow configuration by workflowKey' })
  @ApiParam({ name: 'workflowKey', type: String })
  @ApiResponse({ status: HttpStatus.OK, type: WorkflowConfigurationResponseDto, description: 'Workflow configuration fetched successfully' })
  async getWorkflowByKey(@Param('workflowKey') workflowKey: string, @Res() res: Response) {
    try {
      const workflow = await this.workflowService.getWorkFlowByKey(workflowKey);
      const responseDto = this.workflowService.transformWorkflowToDto(workflow);
      await this.responseService.success(
        res,
        'Workflow configuration fetched successfully',
        responseDto ?? undefined,
        HttpStatus.OK,
      );
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  @Get('id/:workflowId')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Get workflow configuration by workflow ID' })
  @ApiParam({ name: 'workflowId', type: Number })
  @ApiResponse({ status: HttpStatus.OK, type: WorkflowConfigurationResponseDto, description: 'Workflow configuration fetched successfully' })
  async getWorkFlowById(@Param('workflowId', ParseIntPipe) workflowId: number, @Res() res: Response) {
    try {
      const workflow = await this.workflowService.getWorkFlowById(workflowId);
      const responseDto = this.workflowService.transformWorkflowToDto(workflow);
      await this.responseService.success(
        res,
        'Workflow configuration fetched successfully',
        responseDto ?? undefined,
        HttpStatus.OK,
      );
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  @Get('program-type/:programTypeKey')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Get workflow ID by program type key' })
  @ApiParam({ name: 'programTypeKey', type: String, description: 'Program type key (e.g., PT_HDBMSD, PT_ENTRAINMENT)' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Workflow ID fetched successfully' })
  async getWorkflowByProgramType(@Param('programTypeKey') programTypeKey: string, @Res() res: Response) {
    try {
      const workflow = await this.workflowService.getWorkflowByProgramType(programTypeKey);
      const responseData = {
        workflowId: workflow?.id ?? null,
        workflowKey: workflow?.workflowKey ?? null,
        workflowName: workflow?.workflowName ?? null,
        programTypeKey: workflow?.programTypeKey ?? programTypeKey,
      };
      await this.responseService.success(
        res,
        'Workflow ID fetched successfully',
        responseData,
        HttpStatus.OK,
      );
    } catch (error) {
      handleControllerError(res, error);
    }
  }
}
