import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Put,
  UseGuards,
  ValidationPipe,
  ParseIntPipe,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiBearerAuth,
  ApiParam,
  ApiResponse,
} from '@nestjs/swagger';
import { CommissionResponseReasonService } from './commission-response-reason.service';
import { CreateDto } from './dto/create.dto';
import { VcmCommissionResponseReasonEntity } from 'src/entities/VcmCommissionResponseReason.entity';
import { SearchDto } from './dto/search-dto';
import { UpdateDto } from './dto/update.dto';
import { Response } from 'src/config/pagination/paginationDto';
import { UpdateStatusDto } from './dto/update-status.dto';
import { FetchByUsersDto } from './dto/fetch-by-users.dto';
import { handleServiceRequest } from 'src/utils/response/response-handler';
import { SessionGuard } from 'src/config/guards/session.guard';
import {
  UserData,
  UserDataProps,
} from 'src/utils/decorators/user-data.decorator';

/**
 * Commission Response Reason Controller
 *
 * This controller manages CRUD operations for commission response reasons.
 * Commission response reasons are used to categorize and document responses
 * or explanations provided for commission calculations or queries within the
 * visa commission management system.
 *
 * All endpoints are protected by SessionGuard to ensure only authenticated
 * users can access commission response reason data.
 *
 * @ApiTags('Commission Response Reason') - Groups endpoints in Swagger UI
 * @Controller('') - No path prefix, consider adding one
 * @UseGuards(SessionGuard) - Requires valid session for all endpoints
 *
 * @note This controller appears to be nearly identical to the
 * CommissionDifferenceReasonController. Consider creating a generic
 * base controller for shared functionality.
 */
@ApiTags('Commission Response Reason')
@Controller('') // Consider: @Controller('commission-response-reasons')
@UseGuards(SessionGuard)
@ApiBearerAuth() // Indicates endpoints require Bearer token
export class CommissionResponseReasonController {
  constructor(
    private readonly responseReasonService: CommissionResponseReasonService,
  ) {}

  /**
   * Search commission response reasons with filtering and pagination.
   *
   * @param searchDto - Search criteria, filters, and pagination parameters
   * @returns Paginated response of commission response reasons
   *
   * @note Missing ValidationPipe on searchDto parameter
   */
  @Post('all')
  @ApiOperation({
    summary: 'Search commission response reasons',
    description:
      'Search and filter commission response reasons with pagination',
  })
  @ApiResponse({
    status: 200,
    description: 'Commission response reasons retrieved',
  })
  @ApiResponse({ status: 400, description: 'Invalid search parameters' })
  async findAll(
    @Body() searchDto: SearchDto, // Missing ValidationPipe
  ): Promise<Response<VcmCommissionResponseReasonEntity>> {
    return await handleServiceRequest(
      this.responseReasonService.findAll(searchDto),
    );
  }

  /**
   * Get all active commission response reasons.
   *
   * Returns only reasons that are currently marked as active (active = 1).
   * Typically used for dropdowns or selection lists in forms.
   *
   * @returns Response containing all active commission response reasons
   */
  @Get('active')
  @ApiOperation({
    summary: 'Get all active reasons',
    description:
      'Retrieve all commission response reasons that are currently active',
  })
  @ApiResponse({ status: 200, description: 'Active reasons retrieved' })
  async findAllActive(): Promise<Response<VcmCommissionResponseReasonEntity>> {
    return await handleServiceRequest(
      this.responseReasonService.findAllActive(),
    );
  }

  /**
   * Get a specific commission response reason by ID.
   *
   * @param id - Numeric ID of the commission response reason
   * @returns Single commission response reason entity
   *
   * @note Consider adding @ParseIntPipe to ensure ID is parsed as number
   */
  @Get(':id')
  @ApiOperation({
    summary: 'Get reason by ID',
    description: 'Retrieve a specific commission response reason by its ID',
  })
  @ApiParam({
    name: 'id',
    type: Number,
    description: 'Commission response reason ID',
  })
  @ApiResponse({ status: 200, description: 'Reason retrieved' })
  @ApiResponse({ status: 404, description: 'Reason not found' })
  async findOne(@Param('id') id: number) {
    return await handleServiceRequest(this.responseReasonService.findOne(id));
  }

  /**
   * Create a new commission response reason.
   *
   * @param body - Commission response reason data
   * @param userData - Current authenticated user information
   * @returns Newly created commission response reason entity
   */
  @Post()
  @ApiOperation({
    summary: 'Create new reason',
    description: 'Create a new commission response reason',
  })
  @ApiResponse({ status: 201, description: 'Reason created successfully' })
  @ApiResponse({ status: 400, description: 'Invalid input data' })
  async create(
    @Body(new ValidationPipe()) body: CreateDto,
    @UserData() userData: UserDataProps,
  ): Promise<VcmCommissionResponseReasonEntity> {
    return await handleServiceRequest(
      this.responseReasonService.create(userData.id, body),
    );
  }

  /**
   * Update an existing commission response reason.
   *
   * @param body - Updated commission response reason data
   * @param userData - Current authenticated user information
   * @returns Updated commission response reason entity
   */
  @Put()
  @ApiOperation({
    summary: 'Update reason',
    description: 'Update an existing commission response reason',
  })
  @ApiResponse({ status: 200, description: 'Reason updated successfully' })
  @ApiResponse({ status: 404, description: 'Reason not found' })
  async update(
    @Body(new ValidationPipe()) body: UpdateDto,
    @UserData() userData: UserDataProps,
  ) {
    return await handleServiceRequest(
      this.responseReasonService.update(userData.id, body),
    );
  }

  /**
   * Get users who created or updated commission response reasons.
   *
   * This endpoint is useful for audit trails and filtering by user activity.
   *
   * @param params - Filter specifying whether to fetch creators or updaters
   * @returns List of users who created or updated commission response reasons
   */
  @Post('fetch-users')
  @ApiOperation({
    summary: 'Get creators/updaters',
    description: 'Get users who created or updated commission response reasons',
  })
  @ApiResponse({ status: 200, description: 'Users retrieved' })
  async getCreatedByOrUpdatedByUsers(
    @Body(new ValidationPipe()) params: FetchByUsersDto,
  ) {
    return await handleServiceRequest(
      this.responseReasonService.fetchCreatedByOrUpdatedByUsers(params.by),
    );
  }

  /**
   * Bulk update status of commission response reasons.
   *
   * Allows activating or deactivating multiple reasons at once.
   *
   * @param body - Status update action and record IDs
   * @param userData - Current authenticated user information
   * @returns Result of the bulk status update operation
   *
   * @note Missing ValidationPipe on body parameter
   */
  @Post('update-status')
  @ApiOperation({
    summary: 'Bulk update status',
    description: 'Activate or deactivate multiple commission response reasons',
  })
  @ApiResponse({ status: 200, description: 'Status updated successfully' })
  @ApiResponse({ status: 400, description: 'Invalid request data' })
  async updateStatus(
    @Body() body: UpdateStatusDto, // Missing ValidationPipe
    @UserData() userData: UserDataProps,
  ) {
    return await handleServiceRequest(
      this.responseReasonService.updateStatus(userData.id, body),
    );
  }
}
