// 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
import { SearchBonusPaidDto } from './dto/search-dto';
import { FetchByUsersDto } from './dto/fetch-by-users.dto';

// Import utility for consistent error handling
import { handleServiceRequest } from 'src/utils/response/response-handler';

// Import authentication guards
import { SessionGuard } from 'src/config/guards/session.guard';

// Import the service containing business logic
import { SubAgentBonusPaidService } from './sub-agent-bonus-paid.service';

// Import additional DTOs
import { SearchAssociateBanksDto } from './dto/search-associate-banks-dto';
import { CreateBonusPaidDto } from './dto/create-bonus-paid.dto';

// Import file upload related types and interceptors
import { MulterFile } from 'src/constants/types/multer-file.type';
import { AnyFileUpload } from 'src/interceptors/file-upload.interceptor';
import { RemoveAttachmentDto } from './dto/remove-attachment.dto';
import { AddAttachmentDto } from './dto/add-attachment.dto';

// Import custom decorator for user data extraction
import {
  UserData,
  UserDataProps,
} from 'src/utils/decorators/user-data.decorator';

/**
 * SubAgentBonusPaidController - Handles all HTTP requests for sub-agent bonus payment management
 *
 * This controller manages the complete lifecycle of sub-agent bonus payments including:
 * - CRUD operations for bonus payments
 * - File attachment management (upload/view/remove)
 * - Filtering and search with pagination
 * - Reference data for dropdowns (associates, banks, payment modes)
 *
 * Business Context:
 * - Likely part of a commission/bonus management system
 * - Tracks bonus payments made to sub-agents/associates
 * - Manages financial transactions with audit trails
 * - Supports file attachments for transaction proof
 *
 * Security Features:
 * - Session-based authentication (SessionGuard)
 * - User data extraction for audit trails
 * - File upload validation and handling
 *
 * @ApiTags('Sub Agent Bonus Paid') - Groups endpoints in Swagger UI
 * @Controller('') - Base route for this controller
 * @UseGuards(SessionGuard) - Protects all endpoints with session authentication
 */
@ApiTags('Sub Agent Bonus Paid')
@Controller('')
// @UseGuards(AuthGuard) - Commented out alternative guard
// @ApiBearerAuth('defaultBearerAuth') - Commented out bearer auth documentation
@UseGuards(SessionGuard)
export class SubAgentBonusPaidController {
  /**
   * Constructor with dependency injection
   *
   * @param vbrService - Injected service containing all bonus payment business logic
   * Note: Variable name 'vbrService' might be a legacy name or abbreviation
   */
  constructor(private readonly vbrService: SubAgentBonusPaidService) {}

  /**
   * POST /all - Retrieves paginated bonus payments with advanced filtering
   *
   * This endpoint uses POST for complex search criteria (better than GET with query params).
   *
   * @param searchDto - Contains search criteria, filters, and pagination parameters
   * @returns Paginated list of bonus payments with metadata
   */
  @Post('all')
  async findAllInstituteCommissions(
    @Body() searchDto: SearchBonusPaidDto,
  ): Promise<any> {
    return await handleServiceRequest(this.vbrService.findAll(searchDto));
  }

  /**
   * GET /associate-list - Retrieves list of associates for dropdowns
   *
   * @returns List of associates (sub-agents) eligible for bonus payments
   */
  @Get('associate-list')
  async getAssociates() {
    return await handleServiceRequest(this.vbrService.getAssociateList());
  }

  /**
   * GET /company-bank-list - Retrieves company bank accounts
   *
   * @returns List of company bank accounts (source accounts for payments)
   */
  @Get('company-bank-list')
  async getCompanyBanks() {
    return await handleServiceRequest(this.vbrService.getCompanyBankList());
  }

  /**
   * GET /payment-mode-list - Retrieves payment methods
   *
   * @returns List of available payment modes (bank transfer, cash, check, etc.)
   */
  @Get('payment-mode-list')
  async getPaymentModes() {
    return await handleServiceRequest(this.vbrService.getPaymentModeList());
  }

  /**
   * POST /associate-bank-list - Retrieves bank accounts for specific associates
   *
   * Used to fetch bank accounts associated with particular sub-agents.
   *
   * @param params - Contains associate ID to filter bank accounts
   * @returns Bank accounts for the specified associate
   */
  @Post('associate-bank-list')
  async getAssociateBanks(
    @Body(new ValidationPipe()) params: SearchAssociateBanksDto,
  ) {
    return await handleServiceRequest(
      this.vbrService.getAssociateBankList(params),
    );
  }

  /**
   * POST /save-sub-agent-bonus - Creates a new bonus payment with file attachments
   *
   * This endpoint handles bonus payment creation including file uploads.
   * Uses file interceptor for handling uploaded files.
   *
   * @param params - Validated bonus payment data
   * @param files - Uploaded transaction screenshot/files
   * @param userData - Current user's data for audit trail
   * @returns Created bonus payment record
   */
  @Post('save-sub-agent-bonus')
  @UseInterceptors(AnyFileUpload()) // Intercepts and processes uploaded files
  async storeSubAgentBonus(
    @Body(new ValidationPipe()) params: CreateBonusPaidDto,
    @UploadedFiles() files: MulterFile[], // Array of uploaded files
    @UserData() userData: UserDataProps, // Extracted user data from session
  ) {
    // 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-sub-agent-bonus - Updates an existing bonus payment
   *
   * 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 payment update data
   * @param userData - Current user's data for audit trail
   * @returns Updated bonus payment record
   */
  @Post('edit-sub-agent-bonus')
  async editSubAgentBonus(
    @Body(new ValidationPipe()) params: CreateBonusPaidDto,
    @UserData() userData: UserDataProps,
  ) {
    return await handleServiceRequest(
      this.vbrService.update(params, userData.id),
    );
  }

  /**
   * GET /fetch-associates - Alternative endpoint for associate listing
   *
   * May return different data structure or filtering than /associate-list.
   * Used for specific UI components or filters.
   */
  @Get('fetch-associates')
  async getAssociatesByList() {
    return await handleServiceRequest(this.vbrService.fetchAssociatesByList());
  }

  /**
   * GET /fetch-payment-modes - Alternative endpoint for payment mode listing
   */
  @Get('fetch-payment-modes')
  async getPaymentModesByList() {
    return await handleServiceRequest(
      this.vbrService.fetchPaymentModesByList(),
    );
  }

  /**
   * GET /fetch-from-bank-accounts - Retrieves "from" bank accounts for payments
   *
   * Typically company bank accounts used as source for payments.
   */
  @Get('fetch-from-bank-accounts')
  async getFromBankAccountsByList() {
    return await handleServiceRequest(
      this.vbrService.fetchFromBankAccountsByList(),
    );
  }

  /**
   * GET /fetch-to-bank-accounts - Retrieves "to" bank accounts for payments
   *
   * Typically associate/sub-agent bank accounts receiving payments.
   */
  @Get('fetch-to-bank-accounts')
  async getToBankAccountsByList() {
    return await handleServiceRequest(
      this.vbrService.fetchToBankAccountsByList(),
    );
  }

  /**
   * POST /fetch-users - Retrieves users involved in bonus payment operations
   *
   * Used for filter dropdowns in admin interfaces.
   *
   * @param params - Filter type: 'created_by' or 'updated_by'
   * @returns List of users with their activity
   */
  @Post('fetch-users')
  async getCreatedByOrUpdatedByUsers(
    @Body(new ValidationPipe()) params: FetchByUsersDto,
  ) {
    return await handleServiceRequest(
      this.vbrService.fetchCreatedByOrUpdatedByUsers(params.by),
    );
  }

  /**
   * GET /view-attachments/:id - Retrieves attachments for a specific bonus payment
   *
   * @param id - Bonus payment ID to retrieve attachments for
   * @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 payment
   *
   * @param attachment - Contains attachment ID and bonus payment ID
   * @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 payment
   *
   * Uses file interceptor for handling uploaded files.
   *
   * @param body - Contains bonus payment 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),
    );
  }
}
