import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';
import { SYSTEM_ACCOUNTS } from '../../domain/value-objects/pre-planting-right-amounts';

export interface RewardDistributionResult {
  recipientAccountSequence: string;
  isFallback: boolean;
}

/**
 * authorization-service 省/市区域 API 返回的 distributions 数组项
 */
interface AreaDistributionItem {
  accountSequence: string;
  treeCount: number;
  reason: string;
  isSystemAccount: boolean;
}

/**
 * authorization-service 全局 TransformInterceptor 包装格式
 * 所有响应都被包装为 { success: boolean, data: T, timestamp: string }
 */
interface WrappedResponse<T> {
  success: boolean;
  data: T;
  timestamp: string;
}

@Injectable()
export class PrePlantingAuthorizationClient {
  private readonly logger = new Logger(PrePlantingAuthorizationClient.name);
  private readonly baseUrl: string;

  constructor(
    private readonly configService: ConfigService,
    private readonly httpService: HttpService,
  ) {
    this.baseUrl =
      this.configService.get<string>('AUTHORIZATION_SERVICE_URL') ||
      'http://localhost:3006';
  }

  /**
   * 社区权益分配对象
   *
   * treeCount=0：预种阶段不计入社区月度考核，避免 addMonthlyTrees(NaN) 导致 Prisma 报错
   */
  async getCommunityDistribution(
    accountSequence: string,
  ): Promise<RewardDistributionResult> {
    try {
      const response = await firstValueFrom(
        this.httpService.get<WrappedResponse<{ distributions: AreaDistributionItem[] }>>(
          `${this.baseUrl}/api/v1/authorization/community-reward-distribution`,
          { params: { accountSequence, treeCount: 0 } },
        ),
      );

      const distributions = response.data.data.distributions;
      if (!distributions || distributions.length === 0) {
        throw new Error('Empty distributions returned');
      }

      const target = distributions.find(d => !d.isSystemAccount) || distributions[0];

      this.logger.debug(
        `Community distribution for ${accountSequence}: ${target.accountSequence} (${target.reason})`,
      );

      return {
        recipientAccountSequence: target.accountSequence,
        isFallback: false,
      };
    } catch (error) {
      this.logger.warn(
        `Failed to get community distribution for ${accountSequence}, fallback to HQ`,
      );
      return {
        recipientAccountSequence: SYSTEM_ACCOUNTS.HEADQUARTERS,
        isFallback: true,
      };
    }
  }

  /**
   * 省区域权益分配对象
   *
   * [2026-02-28] 修复：
   * 1. 传 treeCount=0（预种阶段不计入省公司月度考核，等合成1棵树后再累计）
   * 2. 正确解析 { success, data: { distributions: [...] } } 包装格式
   * 3. fallback 路径使用 padEnd(6,'0') 右补零，确保生成 7 位标准格式（如 9440000）
   */
  async getProvinceAreaDistribution(
    provinceCode: string,
  ): Promise<RewardDistributionResult> {
    try {
      const response = await firstValueFrom(
        this.httpService.get<WrappedResponse<{ distributions: AreaDistributionItem[] }>>(
          `${this.baseUrl}/api/v1/authorization/province-area-reward-distribution`,
          { params: { provinceCode, treeCount: 0 } },
        ),
      );

      const distributions = response.data.data.distributions;
      if (!distributions || distributions.length === 0) {
        throw new Error('Empty distributions returned');
      }

      // 预种不拆分金额，取第一个分配对象的 accountSequence
      // 如果跨考核达标点有多个 distribution，优先取非系统账户（即省公司）
      const target = distributions.find(d => !d.isSystemAccount) || distributions[0];

      this.logger.debug(
        `Province area distribution for ${provinceCode}: ${target.accountSequence} (${target.reason})`,
      );

      return {
        recipientAccountSequence: target.accountSequence,
        isFallback: false,
      };
    } catch (error) {
      this.logger.warn(
        `Failed to get province area distribution for ${provinceCode}, fallback to system province account`,
      );
      return {
        recipientAccountSequence: `9${provinceCode.padEnd(6, '0')}`,
        isFallback: true,
      };
    }
  }

  /**
   * 省团队权益分配对象
   *
   * treeCount=0：预种阶段不计入省团队月度考核
   */
  async getProvinceTeamDistribution(
    accountSequence: string,
    provinceCode: string,
  ): Promise<RewardDistributionResult> {
    try {
      const response = await firstValueFrom(
        this.httpService.get<WrappedResponse<{ distributions: AreaDistributionItem[] }>>(
          `${this.baseUrl}/api/v1/authorization/province-team-reward-distribution`,
          { params: { accountSequence, provinceCode, treeCount: 0 } },
        ),
      );

      const distributions = response.data.data.distributions;
      if (!distributions || distributions.length === 0) {
        throw new Error('Empty distributions returned');
      }

      const target = distributions.find(d => !d.isSystemAccount) || distributions[0];

      this.logger.debug(
        `Province team distribution for ${accountSequence}: ${target.accountSequence} (${target.reason})`,
      );

      return {
        recipientAccountSequence: target.accountSequence,
        isFallback: false,
      };
    } catch (error) {
      this.logger.warn(
        `Failed to get province team distribution, fallback to HQ`,
      );
      return {
        recipientAccountSequence: SYSTEM_ACCOUNTS.HEADQUARTERS,
        isFallback: true,
      };
    }
  }

  /**
   * 市区域权益分配对象
   *
   * [2026-02-28] 修复：与省区域同样的处理
   * 1. 传 treeCount=0（预种阶段不计入市公司月度考核，等合成1棵树后再累计）
   * 2. 正确解析 { success, data: { distributions: [...] } } 包装格式
   * 3. fallback 路径使用 padEnd(6,'0') 右补零，确保生成 7 位标准格式（如 8440100）
   */
  async getCityAreaDistribution(
    cityCode: string,
  ): Promise<RewardDistributionResult> {
    try {
      const response = await firstValueFrom(
        this.httpService.get<WrappedResponse<{ distributions: AreaDistributionItem[] }>>(
          `${this.baseUrl}/api/v1/authorization/city-area-reward-distribution`,
          { params: { cityCode, treeCount: 0 } },
        ),
      );

      const distributions = response.data.data.distributions;
      if (!distributions || distributions.length === 0) {
        throw new Error('Empty distributions returned');
      }

      // 预种不拆分金额，取第一个分配对象的 accountSequence
      const target = distributions.find(d => !d.isSystemAccount) || distributions[0];

      this.logger.debug(
        `City area distribution for ${cityCode}: ${target.accountSequence} (${target.reason})`,
      );

      return {
        recipientAccountSequence: target.accountSequence,
        isFallback: false,
      };
    } catch (error) {
      this.logger.warn(
        `Failed to get city area distribution for ${cityCode}, fallback to system city account`,
      );
      return {
        recipientAccountSequence: `8${cityCode.padEnd(6, '0')}`,
        isFallback: true,
      };
    }
  }

  /**
   * 市团队权益分配对象
   *
   * treeCount=0：预种阶段不计入市团队月度考核
   */
  async getCityTeamDistribution(
    accountSequence: string,
    cityCode: string,
  ): Promise<RewardDistributionResult> {
    try {
      const response = await firstValueFrom(
        this.httpService.get<WrappedResponse<{ distributions: AreaDistributionItem[] }>>(
          `${this.baseUrl}/api/v1/authorization/city-team-reward-distribution`,
          { params: { accountSequence, cityCode, treeCount: 0 } },
        ),
      );

      const distributions = response.data.data.distributions;
      if (!distributions || distributions.length === 0) {
        throw new Error('Empty distributions returned');
      }

      const target = distributions.find(d => !d.isSystemAccount) || distributions[0];

      this.logger.debug(
        `City team distribution for ${accountSequence}: ${target.accountSequence} (${target.reason})`,
      );

      return {
        recipientAccountSequence: target.accountSequence,
        isFallback: false,
      };
    } catch (error) {
      this.logger.warn(
        `Failed to get city team distribution, fallback to HQ`,
      );
      return {
        recipientAccountSequence: SYSTEM_ACCOUNTS.HEADQUARTERS,
        isFallback: true,
      };
    }
  }
}
