import { Body, Controller, Param, Post, UseGuards } from '@nestjs/common';
import { CommandBus } from '@nestjs/cqrs';
import {
  ApiBearerAuth,
  ApiOperation,
  ApiParam,
  ApiResponse,
  ApiTags,
} from '@nestjs/swagger';
import { CurrentUser, JwtAuthGuard, type JwtPayload, Roles, RolesGuard } from '@modules/auth';
import { ConfirmBankTransferCommand } from '../../application/commands/confirm-bank-transfer/confirm-bank-transfer.command';
import { type ConfirmBankTransferResult } from '../../application/commands/confirm-bank-transfer/confirm-bank-transfer.handler';
import { ConfirmBankTransferDto } from '../dto/confirm-bank-transfer.dto';

/**
 * Admin-only controller for manual payment reconciliation.
 *
 * Separated from the user-facing `PaymentsController` so the audit/RBAC
 * surface is clearly scoped under `/admin/payments/*`.
 */
@ApiTags('admin-payments')
@ApiBearerAuth('JWT')
@Controller('admin/payments')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('ADMIN')
export class AdminPaymentsController {
  constructor(private readonly commandBus: CommandBus) {}

  @Post(':id/confirm-transfer')
  @ApiOperation({
    summary: 'Confirm a VN bank transfer payment (admin only)',
    description:
      'Marks a pending/processing BANK_TRANSFER payment as COMPLETED. ' +
      'Emits payment.completed + payment.bank_transfer_confirmed events ' +
      'so audit logs and subscription activation fire automatically.',
  })
  @ApiParam({ name: 'id', description: 'Payment id to confirm' })
  @ApiResponse({ status: 201, description: 'Bank transfer confirmed successfully' })
  @ApiResponse({ status: 400, description: 'Payment is not a bank transfer or invalid status' })
  @ApiResponse({ status: 401, description: 'Unauthorized — missing or invalid JWT' })
  @ApiResponse({ status: 403, description: 'Forbidden — admin role required' })
  @ApiResponse({ status: 404, description: 'Payment not found' })
  async confirmBankTransfer(
    @Param('id') id: string,
    @Body() dto: ConfirmBankTransferDto,
    @CurrentUser() user: JwtPayload,
  ): Promise<ConfirmBankTransferResult> {
    return this.commandBus.execute(
      new ConfirmBankTransferCommand(id, user.sub, dto.bankReference),
    );
  }
}
