import { Controller, Get, Param, Query, NotFoundException } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiQuery } 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 { GetPlantingLedgerQuery, PlantingLedgerDto } from '../../application/queries/get-planting-ledger.query';
import { GetTeamTreeQuery, DirectReferralsResponseDto, MyTeamInfoDto } from '../../application/queries/get-team-tree.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';
import { Public } from '../../shared/guards/jwt-auth.guard';
import { RequireCapability } from '../../shared/decorators/require-capability.decorator';

@ApiTags('Contribution')
@Controller('contribution')
export class ContributionController {
  constructor(
    private readonly getAccountQuery: GetContributionAccountQuery,
    private readonly getStatsQuery: GetContributionStatsQuery,
    private readonly getRankingQuery: GetContributionRankingQuery,
    private readonly getPlantingLedgerQuery: GetPlantingLedgerQuery,
    private readonly getTeamTreeQuery: GetTeamTreeQuery,
  ) {}

  @Get('stats')
  @Public()
  @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 })
  async getAccount(@Param('accountSequence') accountSequence: string): Promise<ContributionAccountResponse> {
    // 始终返回 200，通过 status 字段区分账户状态：
    // - ACTIVE: 账户正常，有算力数据
    // - INACTIVE: 用户存在但暂无认种记录
    // - USER_NOT_FOUND: 账户不存在
    return this.getAccountQuery.execute(accountSequence);
  }

  @Get('accounts/:accountSequence/records')
  @RequireCapability('VIEW_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')
  @RequireCapability('VIEW_ASSET')
  @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;
  }

  @Get('accounts/:accountSequence/planting-ledger')
  @RequireCapability('VIEW_RECORDS')
  @ApiOperation({ summary: '获取账户认种分类账' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  @ApiQuery({ name: 'page', required: false, type: Number, description: '页码' })
  @ApiQuery({ name: 'pageSize', required: false, type: Number, description: '每页数量' })
  @ApiResponse({ status: 200, description: '认种分类账' })
  async getPlantingLedger(
    @Param('accountSequence') accountSequence: string,
    @Query('page') page?: number,
    @Query('pageSize') pageSize?: number,
  ): Promise<PlantingLedgerDto> {
    return this.getPlantingLedgerQuery.execute(
      accountSequence,
      page ?? 1,
      pageSize ?? 20,
    );
  }

  // ========== 团队树 API ==========

  @Get('accounts/:accountSequence/team')
  @RequireCapability('VIEW_TEAM')
  @ApiOperation({ summary: '获取账户团队信息' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  @ApiResponse({ status: 200, description: '团队信息' })
  async getMyTeamInfo(
    @Param('accountSequence') accountSequence: string,
  ): Promise<MyTeamInfoDto> {
    return this.getTeamTreeQuery.getMyTeamInfo(accountSequence);
  }

  @Get('accounts/:accountSequence/team/direct-referrals')
  @RequireCapability('VIEW_TEAM')
  @ApiOperation({ summary: '获取账户直推列表（用于伞下树懒加载）' })
  @ApiParam({ name: 'accountSequence', description: '账户序号' })
  @ApiQuery({ name: 'limit', required: false, type: Number, description: '每页数量' })
  @ApiQuery({ name: 'offset', required: false, type: Number, description: '偏移量' })
  @ApiResponse({ status: 200, description: '直推列表' })
  async getDirectReferrals(
    @Param('accountSequence') accountSequence: string,
    @Query('limit') limit?: number,
    @Query('offset') offset?: number,
  ): Promise<DirectReferralsResponseDto> {
    return this.getTeamTreeQuery.getDirectReferrals(
      accountSequence,
      limit ?? 100,
      offset ?? 0,
    );
  }
}
