import { Controller, Get, Param, Query, NotFoundException } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiParam } from '@nestjs/swagger';
import { GetContributionAccountQuery } from '../../application/queries/get-contribution-account.query';
import { GetContributionStatsQuery } from '../../application/queries/get-contribution-stats.query';
import { GetContributionRankingQuery } from '../../application/queries/get-contribution-ranking.query';
import {
  ContributionAccountResponse,
  ContributionRecordsResponse,
  ActiveContributionResponse,
} from '../dto/response/contribution-account.response';
import { ContributionStatsResponse } from '../dto/response/contribution-stats.response';
import { ContributionRankingResponse, UserRankResponse } from '../dto/response/contribution-ranking.response';
import { GetContributionRecordsRequest } from '../dto/request/get-records.request';

@ApiTags('Contribution')
@Controller('contributions')
export class ContributionController {
  constructor(
    private readonly getAccountQuery: GetContributionAccountQuery,
    private readonly getStatsQuery: GetContributionStatsQuery,
    private readonly getRankingQuery: GetContributionRankingQuery,
  ) {}

  @Get('stats')
  @ApiOperation({ summary: '获取算力统计数据' })
  @ApiResponse({ status: 200, type: ContributionStatsResponse })
  async getStats(): Promise<ContributionStatsResponse> {
    return this.getStatsQuery.execute();
  }

  @Get('ranking')
  @ApiOperation({ summary: '获取算力排行榜' })
  @ApiResponse({ status: 200, type: ContributionRankingResponse })
  async getRanking(@Query('limit') limit?: number): Promise<ContributionRankingResponse> {
    const data = await this.getRankingQuery.execute(limit ?? 100);
    return { data };
  }

  @Get('accounts/:accountSequence')
  @ApiOperation({ summary: '获取账户算力信息' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  @ApiResponse({ status: 200, type: ContributionAccountResponse })
  @ApiResponse({ status: 404, description: '账户不存在' })
  async getAccount(@Param('accountSequence') accountSequence: string): Promise<ContributionAccountResponse> {
    const account = await this.getAccountQuery.execute(accountSequence);
    if (!account) {
      throw new NotFoundException(`Account ${accountSequence} not found`);
    }
    return account;
  }

  @Get('accounts/:accountSequence/records')
  @ApiOperation({ summary: '获取账户算力明细记录' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  @ApiResponse({ status: 200, type: ContributionRecordsResponse })
  async getRecords(
    @Param('accountSequence') accountSequence: string,
    @Query() query: GetContributionRecordsRequest,
  ): Promise<ContributionRecordsResponse> {
    const result = await this.getAccountQuery.getRecords(accountSequence, {
      sourceType: query.sourceType,
      includeExpired: query.includeExpired,
      page: query.page,
      pageSize: query.pageSize,
    });

    return {
      ...result,
      page: query.page ?? 1,
      pageSize: query.pageSize ?? 50,
    };
  }

  @Get('accounts/:accountSequence/active')
  @ApiOperation({ summary: '获取账户活跃算力统计' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  @ApiResponse({ status: 200, type: ActiveContributionResponse })
  @ApiResponse({ status: 404, description: '账户不存在' })
  async getActiveContribution(@Param('accountSequence') accountSequence: string): Promise<ActiveContributionResponse> {
    const result = await this.getAccountQuery.getActiveContribution(accountSequence);
    if (!result) {
      throw new NotFoundException(`Account ${accountSequence} not found`);
    }
    return result;
  }

  @Get('accounts/:accountSequence/rank')
  @ApiOperation({ summary: '获取账户排名' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  @ApiResponse({ status: 200, type: UserRankResponse })
  @ApiResponse({ status: 404, description: '账户不存在' })
  async getUserRank(@Param('accountSequence') accountSequence: string): Promise<UserRankResponse> {
    const result = await this.getRankingQuery.getUserRank(accountSequence);
    if (!result) {
      throw new NotFoundException(`Account ${accountSequence} not found`);
    }
    return result;
  }
}
