import { Controller, Get, Post, Body, Param, Query } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery } from '@nestjs/swagger';
import { PoolAccountService } from '../../application/services/pool-account.service';
import { AdminOnly, Public } from '../../shared/guards/jwt-auth.guard';
import { PoolAccountType, TransactionType } from '@prisma/client';
import Decimal from 'decimal.js';

class InitializePoolsDto {
  sharePoolA: { name: string; initialBalance?: string };
  sharePoolB: { name: string; initialBalance?: string };
  blackHolePool: { name: string; targetBurn: string };
  circulationPool: { name: string; initialBalance?: string };
}

class BurnToBlackHoleDto {
  amount: string;
  fromPoolType: PoolAccountType;
  counterpartyAccountSeq?: string;
  counterpartyUserId?: string;
  referenceId?: string;
}

class BlockchainWithdrawDto {
  poolType: PoolAccountType;
  amount: string;
  txHash: string;
  toAddress: string;
  blockNumber?: string;
}

@ApiTags('Pool Accounts')
@Controller('pool-accounts')
@ApiBearerAuth()
export class PoolAccountController {
  constructor(private readonly poolAccountService: PoolAccountService) {}

  @Get()
  @AdminOnly()
  @ApiOperation({ summary: '获取所有池账户' })
  @ApiResponse({ status: 200, description: '池账户列表' })
  async findAll() {
    return this.poolAccountService.findAll();
  }

  @Get('share-pool-balance')
  @Public()
  @ApiOperation({ summary: '获取积分股池总余量' })
  @ApiResponse({ status: 200, description: '积分股池A+B的总余量' })
  async getSharePoolTotalBalance() {
    return this.poolAccountService.getSharePoolTotalBalance();
  }

  @Get('stats')
  @AdminOnly()
  @ApiOperation({ summary: '获取池账户统计' })
  async getStats() {
    return this.poolAccountService.getPoolStats();
  }

  @Get(':type')
  @Public()
  @ApiOperation({ summary: '获取特定类型池账户（内网服务间调用）' })
  async findByType(@Param('type') type: PoolAccountType) {
    return this.poolAccountService.findByType(type);
  }

  @Get(':type/transactions')
  @AdminOnly()
  @ApiOperation({ summary: '获取池账户交易记录' })
  @ApiQuery({ name: 'transactionType', required: false })
  @ApiQuery({ name: 'startDate', required: false })
  @ApiQuery({ name: 'endDate', required: false })
  @ApiQuery({ name: 'limit', required: false, type: Number })
  @ApiQuery({ name: 'offset', required: false, type: Number })
  async getTransactions(
    @Param('type') type: PoolAccountType,
    @Query('transactionType') transactionType?: TransactionType,
    @Query('startDate') startDate?: string,
    @Query('endDate') endDate?: string,
    @Query('limit') limit?: number,
    @Query('offset') offset?: number,
  ) {
    return this.poolAccountService.getTransactions(type, {
      transactionType,
      startDate: startDate ? new Date(startDate) : undefined,
      endDate: endDate ? new Date(endDate) : undefined,
      limit: limit ? Number(limit) : undefined,
      offset: offset ? Number(offset) : undefined,
    });
  }

  @Post('initialize')
  @Public()
  @ApiOperation({ summary: '初始化池账户（仅限内网调用）' })
  @ApiResponse({ status: 201, description: '池账户初始化成功' })
  async initialize(@Body() dto: InitializePoolsDto) {
    return this.poolAccountService.initializePools({
      sharePoolA: {
        name: dto.sharePoolA.name,
        initialBalance: dto.sharePoolA.initialBalance
          ? new Decimal(dto.sharePoolA.initialBalance)
          : undefined,
      },
      sharePoolB: {
        name: dto.sharePoolB.name,
        initialBalance: dto.sharePoolB.initialBalance
          ? new Decimal(dto.sharePoolB.initialBalance)
          : undefined,
      },
      blackHolePool: {
        name: dto.blackHolePool.name,
        targetBurn: new Decimal(dto.blackHolePool.targetBurn),
      },
      circulationPool: {
        name: dto.circulationPool.name,
        initialBalance: dto.circulationPool.initialBalance
          ? new Decimal(dto.circulationPool.initialBalance)
          : undefined,
      },
    });
  }

  @Post('burn')
  @AdminOnly()
  @ApiOperation({ summary: '销毁到黑洞池' })
  async burnToBlackHole(@Body() dto: BurnToBlackHoleDto) {
    return this.poolAccountService.burnToBlackHole(new Decimal(dto.amount), {
      fromPoolType: dto.fromPoolType,
      counterpartyAccountSeq: dto.counterpartyAccountSeq,
      counterpartyUserId: dto.counterpartyUserId,
      referenceId: dto.referenceId,
    });
  }

  @Post('blockchain-withdraw')
  @Public()
  @ApiOperation({ summary: '记录区块链提现（仅限内网调用）' })
  @ApiResponse({ status: 200, description: '提现记录成功' })
  async recordBlockchainWithdraw(@Body() dto: BlockchainWithdrawDto) {
    await this.poolAccountService.blockchainWithdraw(
      dto.poolType,
      new Decimal(dto.amount),
      {
        txHash: dto.txHash,
        toAddress: dto.toAddress,
        blockNumber: dto.blockNumber,
      },
    );
    return { success: true };
  }

  @Post('centralized-deposit')
  @Public()
  @ApiOperation({ summary: '中心化充值（仅限内网调用）' })
  @ApiResponse({ status: 200, description: '充值成功' })
  async centralizedDeposit(@Body() dto: { poolType: PoolAccountType; amount: string; adminId?: string }) {
    await this.poolAccountService.centralizedDeposit(
      dto.poolType,
      new Decimal(dto.amount),
      dto.adminId,
    );
    return { success: true };
  }
}
