// Import necessary decorators and utilities from NestJS
import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  UploadedFiles,
  UseGuards,
  UseInterceptors,
  ValidationPipe,
} from '@nestjs/common';

// Import Swagger decorator for API documentation
import { ApiTags } from '@nestjs/swagger';

// Import DTOs for request validation (8 different DTOs)
import { SearchAssociatesDto } from './dto/search-associates-dto';
import { SearchBonusReceivedDto } from './dto/search-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 { FetchByAssociationTypesDto } from './dto/fetch-by-association-types.dto';
import { VisaBonusReceivedService } from './visa-bonus-received.service';
import { AnyFileUpload } from 'src/interceptors/file-upload.interceptor';
import { MulterFile } from 'src/constants/types/multer-file.type';
import { RemoveAttachmentDto } from './dto/remove-attachment.dto';
import { AddAttachmentDto } from './dto/add-attachment.dto';
import { CreateBonusReceivedDto } from './dto/create-bonus-received.dto';
import {
  UserData,
  UserDataProps,
} from 'src/utils/decorators/user-data.decorator';

/**
 * VisaBonusReceivedController - Handles HTTP requests for visa bonus receipt management
 *
 * This controller manages the complete lifecycle of visa bonus receipt tracking including:
 * - CRUD operations for bonus receipt records
 * - File attachment management for transaction proof
 * - Comprehensive filtering and search capabilities
 * - Reference data endpoints for dropdowns and filters
 * - Association type-based filtering for different bonus scenarios
 *
 * Business Context:
 * - Part of a visa/immigration commission management system
 * - Tracks bonuses received from partners/institutes for visa cases
 * - Manages financial transaction documentation
 * - Supports multiple association types (institutes, master agents, etc.)
 *
 * Key Features:
 * - 22+ endpoints for comprehensive bonus management
 * - File upload support for transaction documentation
 * - Multi-type filtering based on association relationships
 * - User activity tracking and audit trails
 * - Session-based authentication for financial operations
 *
 * @ApiTags('Visa Bonus Received') - Groups all endpoints in Swagger UI
 * @Controller('') - Base route for this controller
 * @UseGuards(SessionGuard) - Protects all endpoints with session authentication
 */
@ApiTags('Visa Bonus Received')
@Controller('')
// @UseGuards(AuthGuard) - Commented out alternative authentication guard
// @ApiBearerAuth('defaultBearerAuth') - Commented out bearer auth documentation
@UseGuards(SessionGuard)
export class VisaBonusReceivedController {
  /**
   * Constructor with dependency injection
   *
   * @param vbrService - Injected service containing all bonus receipt business logic
   * Note: 'vbrService' likely stands for "Visa Bonus Received Service"
   */
  constructor(private readonly vbrService: VisaBonusReceivedService) {}

  /**
   * POST /all - Retrieves paginated bonus receipts with advanced filtering
   *
   * Main search endpoint for bonus receipt records.
   * Uses POST for complex search criteria.
   *
   * @param searchDto - Comprehensive search parameters for bonus receipt filtering
   * @returns Paginated list of bonus receipt records with metadata
   */
  @Post('all')
  async findAllInstituteCommissions(
    @Body() searchDto: SearchBonusReceivedDto,
  ): Promise<any> {
    return await handleServiceRequest(this.vbrService.findAll(searchDto));
  }

  /**
   * GET /visa-service-countries - Retrieves visa service countries
   *
   * Returns countries where visa services are offered.
   * Used for dropdowns and geographic filtering.
   *
   * @returns List of visa service countries
   */
  @Get('visa-service-countries')
  async getVisaServiceCountries() {
    return await handleServiceRequest(this.vbrService.getVisaCountryList());
  }

  /**
   * POST /associate-list - Retrieves associates with filtering
   *
   * Associates likely refer to partners, institutes, or agents
   * who pay bonuses for visa cases.
   *
   * @param params - Search parameters for associates (country, type, status, etc.)
   * @returns Filtered list of associates
   */
  @Post('associate-list')
  async getAssociates(@Body(new ValidationPipe()) params: SearchAssociatesDto) {
    return await handleServiceRequest(this.vbrService.getAssociateList(params));
  }

  /**
   * GET /company-bank-list - Retrieves company bank accounts
   *
   * Bank accounts where bonuses are received.
   * Used for transaction recording and reconciliation.
   *
   * @returns List of company bank accounts
   */
  @Get('company-bank-list')
  async getCompanyBanks() {
    return await handleServiceRequest(this.vbrService.getCompanyBankList());
  }

  /**
   * GET /payment-mode-list - Retrieves payment methods
   *
   * Payment methods used for bonus transactions.
   * Examples: Bank Transfer, Cash, Check, Online Payment.
   *
   * @returns List of payment modes
   */
  @Get('payment-mode-list')
  async getPaymentModes() {
    return await handleServiceRequest(this.vbrService.getPaymentModeList());
  }

  // ==================== FETCH BY LIST ENDPOINTS WITH TYPE FILTERING ====================
  // These endpoints support filtering by association type parameter
  // Different association types may have different data relationships

  /**
   * POST /fetch-service-countries - Retrieves distinct service countries with type filter
   *
   * @param params - Contains 'type' parameter for association type filtering
   * @returns Distinct service countries filtered by association type
   */
  @Post('fetch-service-countries')
  async getServiceCountriesByList(
    @Body(new ValidationPipe()) params: FetchByAssociationTypesDto,
  ) {
    return await handleServiceRequest(
      this.vbrService.fetchServiceCountriesByList(params.type),
    );
  }

  /**
   * POST /fetch-associates - Retrieves distinct associates with type filter
   *
   * @param params - Contains 'type' parameter for association type filtering
   * @returns Distinct associates filtered by association type
   */
  @Post('fetch-associates')
  async getAssociatesByList(
    @Body(new ValidationPipe()) params: FetchByAssociationTypesDto,
  ) {
    return await handleServiceRequest(
      this.vbrService.fetchAssociatesByList(params.type),
    );
  }

  /**
   * POST /fetch-payment-modes - Retrieves distinct payment modes with type filter
   *
   * @param params - Contains 'type' parameter for association type filtering
   * @returns Distinct payment modes filtered by association type
   */
  @Post('fetch-payment-modes')
  async getPaymentModesByList(
    @Body(new ValidationPipe()) params: FetchByAssociationTypesDto,
  ) {
    return await handleServiceRequest(
      this.vbrService.fetchPaymentModesByList(params.type),
    );
  }

  /**
   * POST /fetch-received-bank-accounts - Retrieves distinct bank accounts with type filter
   *
   * @param params - Contains 'type' parameter for association type filtering
   * @returns Distinct bank accounts filtered by association type
   */
  @Post('fetch-received-bank-accounts')
  async getReceivedBankAccountsByList(
    @Body(new ValidationPipe()) params: FetchByAssociationTypesDto,
  ) {
    return await handleServiceRequest(
      this.vbrService.fetchReceivedBankAccountsByList(params.type),
    );
  }

  /**
   * POST /fetch-users - Retrieves users involved in bonus operations with type filter
   *
   * @param params - Contains 'by' (created_by/updated_by) and 'type' parameters
   * @returns List of users filtered by activity type and association type
   */
  @Post('fetch-users')
  async getCreatedByOrUpdatedByUsers(
    @Body(new ValidationPipe()) params: FetchByUsersDto,
  ) {
    return await handleServiceRequest(
      this.vbrService.fetchCreatedByOrUpdatedByUsers(params.by, params.type),
    );
  }

  // ==================== ATTACHMENT MANAGEMENT ENDPOINTS ====================

  /**
   * GET /view-attachments/:id - Retrieves attachments for a specific bonus receipt
   *
   * @param id - Bonus receipt ID
   * @returns List of file attachments with metadata
   */
  @Get('view-attachments/:id')
  async getAttachments(@Param('id') id: string) {
    return await handleServiceRequest(this.vbrService.getAttachments(id));
  }

  /**
   * POST /remove-attachment - Removes an attachment from a bonus receipt
   *
   * @param attachment - Contains bonus receipt ID and file name to remove
   * @param userData - Current user's data for audit trail
   * @returns Removal result
   */
  @Post('remove-attachment')
  async removeAttachments(
    @Body(new ValidationPipe()) attachment: RemoveAttachmentDto,
    @UserData() userData: UserDataProps,
  ) {
    return await handleServiceRequest(
      this.vbrService.removeAttachments(attachment, userData),
    );
  }

  /**
   * POST /add-attachment - Adds new attachments to an existing bonus receipt
   *
   * @param body - Contains bonus receipt ID and file metadata
   * @param files - Uploaded files to attach
   * @param userData - Current user's data for audit trail
   * @returns Added attachments result
   */
  @Post('add-attachment')
  @UseInterceptors(AnyFileUpload())
  async addAttachments(
    @Body(new ValidationPipe()) body: AddAttachmentDto,
    @UploadedFiles() files: MulterFile[],
    @UserData() userData: UserDataProps,
  ) {
    // Map uploaded files to filenames
    body.attachment_file = files?.map((file) => file.filename) || null;
    return await handleServiceRequest(
      this.vbrService.addAttachments(body, userData),
    );
  }

  /**
   * POST /save-bonus - Creates a new bonus receipt with file attachments
   *
   * Main endpoint for creating bonus receipt records.
   * Supports file uploads for transaction documentation.
   *
   * @param params - Validated bonus receipt creation data
   * @param files - Uploaded transaction screenshot/files
   * @param userData - Current user's data for audit trail
   * @returns Created bonus receipt record
   */
  @Post('save-bonus')
  @UseInterceptors(AnyFileUpload())
  async storeBonus(
    @Body(new ValidationPipe()) params: CreateBonusReceivedDto,
    @UploadedFiles() files: MulterFile[],
    @UserData() userData: UserDataProps,
  ) {
    // Map uploaded files to filenames for storage
    const transactionScreenshot = files?.map((file) => file.filename) || null;
    params.attachment_file = transactionScreenshot;

    return await handleServiceRequest(
      this.vbrService.create(params, userData.id),
    );
  }

  /**
   * POST /edit-bonus - Updates an existing bonus receipt
   *
   * Note: This endpoint doesn't support file uploads for updates.
   * File attachments must be managed separately via add/remove attachment endpoints.
   *
   * @param params - Validated bonus receipt update data
   * @param userData - Current user's data for audit trail
   * @returns Updated bonus receipt record
   */
  @Post('edit-bonus')
  async editBonus(
    @Body(new ValidationPipe()) params: CreateBonusReceivedDto,
    @UserData() userData: UserDataProps,
  ) {
    return await handleServiceRequest(
      this.vbrService.update(params, userData.id),
    );
  }
}
