import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  Res,
  Req,
  HttpStatus,
  HttpCode,
  UseGuards,
  ParseIntPipe,
} from '@nestjs/common';
import { Response } from 'express';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiQuery,
  ApiBearerAuth,
  ApiSecurity,
  ApiParam,
} from '@nestjs/swagger';
import { MasterQuestionService } from './master-question.service';
import { CreateMasterQuestionDto } from './dto/create-master-question.dto';
import { UpdateMasterQuestionDto } from './dto/update-master-question.dto';
import { FilterMasterQuestionDto } from './dto/filter-master-question.dto';
import { ResponseService } from 'src/common/response-handling/response-handler';
import { Roles } from 'src/common/decorators/roles.decorator';
import { RolesGuard } from 'src/common/guards/roles.guard';
import { AppLoggerService } from 'src/common/services/logger.service';
import { handleControllerError } from 'src/common/utils/controller-response-handling';
import { CombinedAuthGuard } from 'src/auth/combined-auth.guard';

@ApiTags('master-question')
@Controller('v1/master-questions')
@UseGuards(CombinedAuthGuard, RolesGuard)
@Roles('admin', 'shoba')
@ApiBearerAuth('Authorization')
@ApiSecurity('userIdAuth')
@ApiSecurity('activeRoleAuth')
export class MasterQuestionController {
  constructor(
    private readonly masterQuestionService: MasterQuestionService,
    private readonly responseService: ResponseService,
    private readonly logger: AppLoggerService,
  ) {}

  /**
   * Get all master questions with filters
   */
  @Get()
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Get all master questions with filters' })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'offset', required: false, type: Number })
  @ApiQuery({ name: 'searchText', required: false, type: String })
  @ApiQuery({ name: 'isActive', required: false, type: Boolean })
  @ApiQuery({ name: 'masterFormSectionId', required: false, type: Number })
  @ApiQuery({ name: 'questionType', required: false, type: String })
  @ApiQuery({ name: 'answerType', required: false, type: String })
  @ApiResponse({ status: HttpStatus.OK, description: 'Master questions retrieved successfully' })
  @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: 'Internal server error' })
  async findAll(@Query() filters: FilterMasterQuestionDto, @Res() res: Response) {
    this.logger.log('GET /v1/master-questions - Request received', { filters });
    try {
      const result = await this.masterQuestionService.findAll(filters);
      this.logger.log('Master questions retrieved successfully');
      return this.responseService.success(res, 'Master questions retrieved successfully', result);
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  /**
   * Get a single master question by ID
   */
  @Get(':id')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Get a master question by ID' })
  @ApiParam({ name: 'id', type: Number, description: 'Master question ID' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Master question retrieved successfully' })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Master question not found' })
  @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: 'Internal server error' })
  async findById(@Param('id', ParseIntPipe) id: number, @Res() res: Response) {
    this.logger.log('GET /v1/master-questions/:id - Request received', { id });
    try {
      const result = await this.masterQuestionService.findById(id);
      this.logger.log('Master question retrieved successfully');
      return this.responseService.success(res, 'Master question retrieved successfully', result);
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  /**
   * Create a new master question
   */
  @Post()
  @HttpCode(HttpStatus.CREATED)
  @ApiOperation({ summary: 'Create a new master question' })
  @ApiResponse({ status: HttpStatus.CREATED, description: 'Master question created successfully' })
  @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Bad request' })
  @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: 'Internal server error' })
  async create(@Body() createDto: CreateMasterQuestionDto, @Req() req: any, @Res() res: Response) {
    this.logger.log('POST /v1/master-questions - Request received', { createDto });
    try {
      const userId = req.user?.id;
      if (userId) {
        createDto.createdBy = userId;
        createDto.updatedBy = userId;
      }
      const result = await this.masterQuestionService.create(createDto);
      this.logger.log('Master question created successfully');
      return this.responseService.success(res, 'Master question created successfully', result, HttpStatus.CREATED);
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  /**
   * Update a master question
   */
  @Put(':id')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Update a master question' })
  @ApiParam({ name: 'id', type: Number, description: 'Master question ID' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Master question updated successfully' })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Master question not found' })
  @ApiResponse({ status: HttpStatus.BAD_REQUEST, description: 'Bad request' })
  @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: 'Internal server error' })
  async update(
    @Param('id', ParseIntPipe) id: number,
    @Body() updateDto: UpdateMasterQuestionDto,
    @Req() req: any,
    @Res() res: Response,
  ) {
    this.logger.log('PUT /v1/master-questions/:id - Request received', { id, updateDto });
    try {
      const userId = req.user?.id;
      if (userId) {
        updateDto.updatedBy = userId;
      }
      const result = await this.masterQuestionService.update(id, updateDto);
      this.logger.log('Master question updated successfully');
      return this.responseService.success(res, 'Master question updated successfully', result ?? undefined);
    } catch (error) {
      handleControllerError(res, error);
    }
  }

  /**
   * Soft delete a master question
   */
  @Delete(':id')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: 'Delete a master question' })
  @ApiParam({ name: 'id', type: Number, description: 'Master question ID' })
  @ApiResponse({ status: HttpStatus.OK, description: 'Master question deleted successfully' })
  @ApiResponse({ status: HttpStatus.NOT_FOUND, description: 'Master question not found' })
  @ApiResponse({ status: HttpStatus.INTERNAL_SERVER_ERROR, description: 'Internal server error' })
  async delete(@Param('id', ParseIntPipe) id: number, @Req() req: any, @Res() res: Response) {
    this.logger.log('DELETE /v1/master-questions/:id - Request received', { id });
    try {
      const userId = req.user?.id;
      await this.masterQuestionService.delete(id, userId);
      this.logger.log('Master question deleted successfully');
      return this.responseService.success(res, 'Master question deleted successfully', { id });
    } catch (error) {
      handleControllerError(res, error);
    }
  }
}
