import { Controller, Get, Post, Put, Delete, Param, Body, Query, UseGuards, Inject } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth, ApiQuery, ApiParam } from '@nestjs/swagger';
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
import { AdminGuard } from '../guards/admin.guard';
import {
  VirtualAccountResponseDto,
  GenerateVirtualAccountsDto,
  UpdateVirtualAccountDto,
} from '../dto/virtual-account.dto';
import { VirtualRankingGeneratorService } from '../../domain/services/virtual-ranking-generator.service';
import {
  IVirtualAccountRepository,
  VIRTUAL_ACCOUNT_REPOSITORY,
} from '../../domain/repositories/virtual-account.repository.interface';
import { VirtualAccountType } from '../../domain/value-objects/virtual-account-type.enum';

@ApiTags('虚拟账户')
@Controller('virtual-accounts')
@UseGuards(JwtAuthGuard, AdminGuard)
@ApiBearerAuth()
export class VirtualAccountController {
  constructor(
    private readonly virtualRankingGenerator: VirtualRankingGeneratorService,
    @Inject(VIRTUAL_ACCOUNT_REPOSITORY)
    private readonly virtualAccountRepository: IVirtualAccountRepository,
  ) {}

  @Get()
  @ApiOperation({ summary: '获取虚拟账户列表' })
  @ApiQuery({ name: 'type', enum: VirtualAccountType, required: false, description: '账户类型' })
  @ApiResponse({
    status: 200,
    description: '虚拟账户列表',
    type: [VirtualAccountResponseDto],
  })
  async getVirtualAccounts(@Query('type') type?: VirtualAccountType) {
    let accounts;

    if (type) {
      accounts = await this.virtualAccountRepository.findByType(type);
    } else {
      // 获取所有类型
      accounts = [];
      for (const t of Object.values(VirtualAccountType)) {
        const typeAccounts = await this.virtualAccountRepository.findByType(t as VirtualAccountType);
        accounts.push(...typeAccounts);
      }
    }

    return {
      code: 0,
      message: 'success',
      data: accounts.map((account) => ({
        id: account.id?.toString(),
        accountType: account.accountType,
        displayName: account.displayName,
        avatar: account.avatar,
        provinceCode: account.provinceCode,
        cityCode: account.cityCode,
        minScore: account.minScore,
        maxScore: account.maxScore,
        currentScore: account.currentScore,
        usdtBalance: account.usdtBalance,
        hashpowerBalance: account.hashpowerBalance,
        isActive: account.isActive,
        createdAt: account.createdAt.toISOString(),
      })),
    };
  }

  @Post('generate')
  @ApiOperation({ summary: '批量生成虚拟账户' })
  @ApiResponse({ status: 201, description: '生成成功' })
  async generateVirtualAccounts(@Body() dto: GenerateVirtualAccountsDto) {
    const accounts = await this.virtualRankingGenerator.batchCreateVirtualAccounts({
      count: dto.count,
      minScore: dto.minScore,
      maxScore: dto.maxScore,
    });

    return {
      code: 0,
      message: `成功生成 ${accounts.length} 个虚拟账户`,
      data: {
        count: accounts.length,
      },
    };
  }

  @Get(':id')
  @ApiOperation({ summary: '获取虚拟账户详情' })
  @ApiParam({ name: 'id', description: '账户ID' })
  @ApiResponse({
    status: 200,
    description: '虚拟账户详情',
    type: VirtualAccountResponseDto,
  })
  async getVirtualAccount(@Param('id') id: string) {
    const account = await this.virtualAccountRepository.findById(BigInt(id));

    if (!account) {
      return {
        code: 404,
        message: '虚拟账户不存在',
      };
    }

    return {
      code: 0,
      message: 'success',
      data: {
        id: account.id?.toString(),
        accountType: account.accountType,
        displayName: account.displayName,
        avatar: account.avatar,
        provinceCode: account.provinceCode,
        cityCode: account.cityCode,
        minScore: account.minScore,
        maxScore: account.maxScore,
        currentScore: account.currentScore,
        usdtBalance: account.usdtBalance,
        hashpowerBalance: account.hashpowerBalance,
        isActive: account.isActive,
        createdAt: account.createdAt.toISOString(),
      },
    };
  }

  @Put(':id')
  @ApiOperation({ summary: '更新虚拟账户' })
  @ApiParam({ name: 'id', description: '账户ID' })
  @ApiResponse({ status: 200, description: '更新成功' })
  async updateVirtualAccount(
    @Param('id') id: string,
    @Body() dto: UpdateVirtualAccountDto,
  ) {
    const account = await this.virtualAccountRepository.findById(BigInt(id));

    if (!account) {
      return {
        code: 404,
        message: '虚拟账户不存在',
      };
    }

    if (dto.displayName || dto.avatar !== undefined) {
      account.updateDisplayInfo(dto.displayName || account.displayName, dto.avatar);
    }

    if (dto.minScore !== undefined && dto.maxScore !== undefined) {
      account.updateScoreRange(dto.minScore, dto.maxScore);
    }

    await this.virtualAccountRepository.save(account);

    return {
      code: 0,
      message: '虚拟账户更新成功',
    };
  }

  @Delete(':id')
  @ApiOperation({ summary: '删除虚拟账户' })
  @ApiParam({ name: 'id', description: '账户ID' })
  @ApiResponse({ status: 200, description: '删除成功' })
  async deleteVirtualAccount(@Param('id') id: string) {
    const account = await this.virtualAccountRepository.findById(BigInt(id));

    if (!account) {
      return {
        code: 404,
        message: '虚拟账户不存在',
      };
    }

    // 系统账户不能删除
    if (account.isSystemAccount()) {
      return {
        code: 400,
        message: '系统账户不能删除',
      };
    }

    await this.virtualAccountRepository.deleteById(BigInt(id));

    return {
      code: 0,
      message: '虚拟账户删除成功',
    };
  }

  @Put(':id/activate')
  @ApiOperation({ summary: '激活虚拟账户' })
  @ApiParam({ name: 'id', description: '账户ID' })
  @ApiResponse({ status: 200, description: '激活成功' })
  async activateVirtualAccount(@Param('id') id: string) {
    const account = await this.virtualAccountRepository.findById(BigInt(id));

    if (!account) {
      return {
        code: 404,
        message: '虚拟账户不存在',
      };
    }

    account.activate();
    await this.virtualAccountRepository.save(account);

    return {
      code: 0,
      message: '虚拟账户激活成功',
    };
  }

  @Put(':id/deactivate')
  @ApiOperation({ summary: '停用虚拟账户' })
  @ApiParam({ name: 'id', description: '账户ID' })
  @ApiResponse({ status: 200, description: '停用成功' })
  async deactivateVirtualAccount(@Param('id') id: string) {
    const account = await this.virtualAccountRepository.findById(BigInt(id));

    if (!account) {
      return {
        code: 404,
        message: '虚拟账户不存在',
      };
    }

    account.deactivate();
    await this.virtualAccountRepository.save(account);

    return {
      code: 0,
      message: '虚拟账户停用成功',
    };
  }
}
