import {
  Controller,
  Get,
  Post,
  Query,
  Param,
  Body,
  UseGuards,
  HttpCode,
  HttpStatus,
  Inject,
  Logger,
} from '@nestjs/common';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBearerAuth,
  ApiParam,
} from '@nestjs/swagger';
import { JwtAuthGuard } from '../guards';
import { CurrentUser } from '../decorators';
import { ReferralService } from '../../application/services';
import {
  ValidateReferralCodeDto,
  GetDirectReferralsDto,
  ReferralInfoResponseDto,
  DirectReferralsResponseDto,
  ValidateCodeResponseDto,
  CreateReferralDto,
} from '../dto';
import { CreateReferralRelationshipCommand } from '../../application/commands';
import { GetUserReferralInfoQuery, GetDirectReferralsQuery } from '../../application/queries';
import {
  REFERRAL_RELATIONSHIP_REPOSITORY,
  IReferralRelationshipRepository,
  TEAM_STATISTICS_REPOSITORY,
  ITeamStatisticsRepository,
} from '../../domain';
import { AuthorizationServiceClient } from '../../infrastructure/external';

@ApiTags('Referral')
@Controller('referral')
export class ReferralController {
  constructor(
    private readonly referralService: ReferralService,
    @Inject(REFERRAL_RELATIONSHIP_REPOSITORY)
    private readonly referralRepo: IReferralRelationshipRepository,
    @Inject(TEAM_STATISTICS_REPOSITORY)
    private readonly teamStatsRepo: ITeamStatisticsRepository,
  ) {}

  @Get('me')
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: '获取当前用户推荐信息' })
  @ApiResponse({ status: 200, type: ReferralInfoResponseDto })
  async getMyReferralInfo(@CurrentUser('accountSequence') accountSequence: string): Promise<ReferralInfoResponseDto> {
    this.logger.log(`[getMyReferralInfo] accountSequence from JWT: ${accountSequence}`);
    // 直接使用JWT中的accountSequence查询
    const query = new GetUserReferralInfoQuery(accountSequence);
    return this.referralService.getUserReferralInfo(query);
  }

  @Get('me/direct-referrals')
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: '获取当前用户直推列表' })
  @ApiResponse({ status: 200, type: DirectReferralsResponseDto })
  async getMyDirectReferrals(
    @CurrentUser('accountSequence') accountSequence: string,
    @Query() dto: GetDirectReferralsDto,
  ): Promise<DirectReferralsResponseDto> {
    const query = new GetDirectReferralsQuery(accountSequence, dto.limit, dto.offset);
    return this.referralService.getDirectReferrals(query);
  }

  @Get('validate/:code')
  @ApiOperation({ summary: '验证推荐码是否有效' })
  @ApiParam({ name: 'code', description: '推荐码' })
  @ApiResponse({ status: 200, type: ValidateCodeResponseDto })
  async validateCode(@Param('code') code: string): Promise<ValidateCodeResponseDto> {
    const referrer = await this.referralService.getReferrerByCode(code.toUpperCase());
    return {
      valid: referrer !== null,
      referrerId: referrer?.userId,
    };
  }

  @Post('validate')
  @HttpCode(HttpStatus.OK)
  @ApiOperation({ summary: '验证推荐码 (POST方式)' })
  @ApiResponse({ status: 200, type: ValidateCodeResponseDto })
  async validateCodePost(@Body() dto: ValidateReferralCodeDto): Promise<ValidateCodeResponseDto> {
    const referrer = await this.referralService.getReferrerByCode(dto.code.toUpperCase());
    return {
      valid: referrer !== null,
      referrerId: referrer?.userId,
    };
  }

  private readonly logger = new Logger(ReferralController.name);

  /**
   * 获取用户的推荐链（内部API，供 reward-service 调用）
   * 返回直接推荐人及其认种状态
   *
   * @param accountSequence 支持两种格式：
   *   - accountSequence 格式: D25121300006 或 25121300006 (去掉D前缀)
   *   - 纯数字 userId 格式: 2 (旧格式，不推荐)
   */
  @Get('chain/:accountSequence')
  @ApiOperation({ summary: '获取用户推荐链（内部API）' })
  @ApiParam({ name: 'accountSequence', description: '用户标识 (accountSequence 或 userId)' })
  @ApiResponse({
    status: 200,
    description: '推荐链数据',
    schema: {
      type: 'object',
      properties: {
        ancestors: {
          type: 'array',
          items: {
            type: 'object',
            properties: {
              userId: { type: 'string' },
              accountSequence: { type: 'string' },
              hasPlanted: { type: 'boolean' },
            },
          },
        },
      },
    },
  })
  async getReferralChainForReward(
    @Param('accountSequence') accountSequence: string,
  ): Promise<{ ancestors: Array<{ userId: string; accountSequence: string; hasPlanted: boolean }> }> {
    this.logger.log(`[INTERNAL] getReferralChain: accountSequence=${accountSequence}`);

    let relationship;

    // 判断传入的是 accountSequence 还是 userId
    // accountSequence 格式: D25121300006 或 25121300006 (11位数字或D+11位数字)
    if (accountSequence.startsWith('D') || accountSequence.length >= 11) {
      // 使用 accountSequence 查询
      const normalizedSequence = accountSequence.startsWith('D') ? accountSequence : `D${accountSequence}`;
      this.logger.log(`Using accountSequence query: ${normalizedSequence}`);
      relationship = await this.referralRepo.findByAccountSequence(normalizedSequence);
    } else {
      // 尝试作为 userId 查询 (向后兼容)
      this.logger.log(`Using userId query: ${accountSequence}`);
      try {
        const userIdBigInt = BigInt(accountSequence);
        relationship = await this.referralRepo.findByUserId(userIdBigInt);
      } catch {
        this.logger.warn(`Invalid userId format: ${accountSequence}`);
        return { ancestors: [] };
      }
    }

    if (!relationship || !relationship.referrerId) {
      this.logger.log(`No referral found for accountSequence: ${accountSequence}`);
      return { ancestors: [] };
    }

    // 获取直接推荐人的认种状态
    const referrerId = relationship.referrerId;
    const referrerStats = await this.teamStatsRepo.findByUserId(referrerId);
    const hasPlanted = referrerStats ? referrerStats.personalPlantingCount > 0 : false;

    // 获取推荐人的 accountSequence
    const referrerRelationship = await this.referralRepo.findByUserId(referrerId);
    const referrerAccountSequence = referrerRelationship?.accountSequence || referrerId.toString();

    this.logger.log(`Found referrer: userId=${referrerId}, accountSequence=${referrerAccountSequence}, hasPlanted=${hasPlanted}`);

    return {
      ancestors: [
        {
          userId: referrerId.toString(),
          accountSequence: referrerAccountSequence,
          hasPlanted,
        },
      ],
    };
  }

  @Post()
  @ApiOperation({ summary: '创建推荐关系 (内部接口)' })
  @ApiResponse({ status: 201, description: '创建成功' })
  async createReferralRelationship(
    @Body() dto: CreateReferralDto,
  ): Promise<{ referralCode: string }> {
    const command = new CreateReferralRelationshipCommand(
      BigInt(dto.userId),
      dto.accountSequence,
      dto.referralCode,
      dto.referrerCode ?? null,
      dto.inviterAccountSequence ?? null,
    );
    return this.referralService.createReferralRelationship(command);
  }

  @Get('user/:userId')
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: '获取指定用户推荐信息' })
  @ApiParam({ name: 'userId', description: '用户ID' })
  @ApiResponse({ status: 200, type: ReferralInfoResponseDto })
  async getUserReferralInfo(@Param('userId') userId: string): Promise<ReferralInfoResponseDto> {
    const query = new GetUserReferralInfoQuery(userId);  // userId 已经是字符串
    return this.referralService.getUserReferralInfo(query);
  }

  @Get('user/:accountSequence/direct-referrals')
  @UseGuards(JwtAuthGuard)
  @ApiBearerAuth()
  @ApiOperation({ summary: '获取指定用户的直推列表（用于伞下树懒加载）' })
  @ApiParam({ name: 'accountSequence', description: '账户序列号 (格式: D + YYMMDD + 5位序号)' })
  @ApiResponse({ status: 200, type: DirectReferralsResponseDto })
  async getUserDirectReferrals(
    @Param('accountSequence') accountSequence: string,
    @Query() dto: GetDirectReferralsDto,
  ): Promise<DirectReferralsResponseDto> {
    this.logger.log(`[getUserDirectReferrals] accountSequence=${accountSequence}, limit=${dto.limit}, offset=${dto.offset}`);
    const query = new GetDirectReferralsQuery(accountSequence, dto.limit, dto.offset);
    return this.referralService.getDirectReferrals(query);
  }
}

/**
 * 内部API控制器 - 供其他微服务调用
 * 不需要JWT认证
 */
@ApiTags('Internal Referral API')
@Controller('referrals')
export class InternalReferralController {
  private readonly logger = new Logger(InternalReferralController.name);

  constructor(
    private readonly referralService: ReferralService,
    private readonly authorizationClient: AuthorizationServiceClient,
  ) {}

  @Get(':accountSequence/context')
  @ApiOperation({ summary: '获取用户推荐上下文信息(内部API)' })
  @ApiParam({ name: 'accountSequence', description: '账户序列号' })
  @ApiResponse({ status: 200, description: '推荐上下文' })
  async getReferralContext(
    @Param('accountSequence') accountSequence: string,
    @Query('provinceCode') provinceCode: string,
    @Query('cityCode') cityCode: string,
  ) {
    // 1. 获取用户的推荐链
    const query = new GetUserReferralInfoQuery(accountSequence);  // accountSequence 现在是字符串
    const referralInfo = await this.referralService.getUserReferralInfo(query);

    // 2. 并行查询授权信息（省/市/社区）
    // 使用 fallback 机制：如果 authorization-service 不可用，返回 null
    const authorizations = await this.authorizationClient.findAllNearestAuthorizations(
      accountSequence,  // accountSequence 现在是字符串
      provinceCode,
      cityCode,
    );

    this.logger.debug(
      `[getReferralContext] accountSequence=${accountSequence}, ` +
        `provinceCode=${provinceCode}, cityCode=${cityCode}, ` +
        `referrerId=${referralInfo.referrerId}, ` +
        `nearestCommunity=${authorizations.nearestCommunity}, ` +
        `nearestProvinceAuth=${authorizations.nearestProvinceAuth}, ` +
        `nearestCityAuth=${authorizations.nearestCityAuth}`,
    );

    // 3. 返回完整的推荐上下文信息
    return {
      accountSequence,
      referralChain: referralInfo.referrerId ? [referralInfo.referrerId] : [],
      referrerId: referralInfo.referrerId,
      nearestProvinceAuth: authorizations.nearestProvinceAuth ?? null,  // 已经是字符串，不需要 toString()
      nearestCityAuth: authorizations.nearestCityAuth ?? null,  // 已经是字符串，不需要 toString()
      nearestCommunity: authorizations.nearestCommunity ?? null,  // 已经是字符串，不需要 toString()
    };
  }
}
