import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { IAuthorizationServiceClient, RewardDistribution, AreaRewardDistribution } from '../../../domain/services/reward-calculation.service';

// authorization-service 返回格式（经过 TransformInterceptor 包装）
interface AuthorizationServiceResponse<T> {
  success: boolean;
  data: T;
  timestamp: string;
}

interface NearestAuthorizationResult {
  accountSequence: string | null;
}

interface RewardDistributionResult {
  distributions: Array<{
    accountSequence: string;
    treeCount: number;
    reason: string;
  }>;
}

interface AreaRewardDistributionResult {
  distributions: Array<{
    accountSequence: string;
    treeCount: number;
    reason: string;
    isSystemAccount: boolean;
  }>;
}

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

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

  async findNearestAuthorizedProvince(accountSequence: string, provinceCode: string): Promise<string | null> {
    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/nearest-province?accountSequence=${accountSequence}&provinceCode=${provinceCode}`,
      );

      if (!response.ok) {
        this.logger.warn(`No authorized province found for accountSequence ${accountSequence}, province ${provinceCode}`);
        return null;
      }

      // authorization-service 返回格式: { success, data: { accountSequence }, timestamp }
      const result: AuthorizationServiceResponse<NearestAuthorizationResult> = await response.json();
      return result.data?.accountSequence || null;
    } catch (error) {
      this.logger.error(`Error finding nearest authorized province:`, error);
      return null;
    }
  }

  async findNearestAuthorizedCity(accountSequence: string, cityCode: string): Promise<string | null> {
    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/nearest-city?accountSequence=${accountSequence}&cityCode=${cityCode}`,
      );

      if (!response.ok) {
        this.logger.warn(`No authorized city found for accountSequence ${accountSequence}, city ${cityCode}`);
        return null;
      }

      // authorization-service 返回格式: { success, data: { accountSequence }, timestamp }
      const result: AuthorizationServiceResponse<NearestAuthorizationResult> = await response.json();
      return result.data?.accountSequence || null;
    } catch (error) {
      this.logger.error(`Error finding nearest authorized city:`, error);
      return null;
    }
  }

  async findNearestCommunity(accountSequence: string): Promise<string | null> {
    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/nearest-community?accountSequence=${accountSequence}`,
      );

      if (!response.ok) {
        this.logger.warn(`No community found for accountSequence ${accountSequence}`);
        return null;
      }

      // authorization-service 返回格式: { success, data: { accountSequence }, timestamp }
      const result: AuthorizationServiceResponse<NearestAuthorizationResult> = await response.json();
      const resultAccountSeq = result.data?.accountSequence;
      this.logger.debug(`findNearestCommunity for accountSequence=${accountSequence}: result=${resultAccountSeq}`);
      return resultAccountSeq || null;
    } catch (error) {
      this.logger.error(`Error finding nearest community:`, error);
      return null;
    }
  }

  async getCommunityRewardDistribution(accountSequence: string, treeCount: number): Promise<RewardDistribution> {
    const HEADQUARTERS_ACCOUNT_SEQUENCE = 'S0000000001';
    const defaultDistribution: RewardDistribution = {
      distributions: [
        {
          accountSequence: HEADQUARTERS_ACCOUNT_SEQUENCE,
          treeCount,
          reason: '服务调用失败，默认进总部社区',
        },
      ],
    };

    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/community-reward-distribution?accountSequence=${accountSequence}&treeCount=${treeCount}`,
      );

      if (!response.ok) {
        this.logger.warn(`Failed to get community reward distribution for accountSequence ${accountSequence}, treeCount ${treeCount}`);
        return defaultDistribution;
      }

      // authorization-service 返回格式: { success, data: { distributions }, timestamp }
      const result: AuthorizationServiceResponse<RewardDistributionResult> = await response.json();

      if (!result.data?.distributions || result.data.distributions.length === 0) {
        this.logger.warn(`Empty distributions returned for accountSequence ${accountSequence}`);
        return defaultDistribution;
      }

      this.logger.debug(
        `getCommunityRewardDistribution for accountSequence=${accountSequence}, treeCount=${treeCount}: ` +
        `distributions=${JSON.stringify(result.data.distributions)}`,
      );

      return result.data;
    } catch (error) {
      this.logger.error(`Error getting community reward distribution:`, error);
      return defaultDistribution;
    }
  }

  async getProvinceTeamRewardDistribution(accountSequence: string, provinceCode: string, treeCount: number): Promise<RewardDistribution> {
    const HEADQUARTERS_ACCOUNT_SEQUENCE = 'S0000000001';
    const defaultDistribution: RewardDistribution = {
      distributions: [
        {
          accountSequence: HEADQUARTERS_ACCOUNT_SEQUENCE,
          treeCount,
          reason: '服务调用失败，默认进总部社区',
        },
      ],
    };

    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/province-team-reward-distribution?accountSequence=${accountSequence}&provinceCode=${provinceCode}&treeCount=${treeCount}`,
      );

      if (!response.ok) {
        this.logger.warn(`Failed to get province team reward distribution for accountSequence ${accountSequence}, province ${provinceCode}`);
        return defaultDistribution;
      }

      const result: AuthorizationServiceResponse<RewardDistributionResult> = await response.json();

      if (!result.data?.distributions || result.data.distributions.length === 0) {
        this.logger.warn(`Empty province team distributions returned for accountSequence ${accountSequence}`);
        return defaultDistribution;
      }

      this.logger.debug(
        `getProvinceTeamRewardDistribution for accountSequence=${accountSequence}, provinceCode=${provinceCode}, treeCount=${treeCount}: ` +
        `distributions=${JSON.stringify(result.data.distributions)}`,
      );

      return result.data;
    } catch (error) {
      this.logger.error(`Error getting province team reward distribution:`, error);
      return defaultDistribution;
    }
  }

  async getProvinceAreaRewardDistribution(provinceCode: string, treeCount: number): Promise<AreaRewardDistribution> {
    // 系统省账户ID: 9 + provinceCode (6位)
    const systemProvinceAccountId = `9${provinceCode.padStart(6, '0')}`;
    const defaultDistribution: AreaRewardDistribution = {
      distributions: [
        {
          accountSequence: systemProvinceAccountId,
          treeCount,
          reason: '服务调用失败，默认进系统省账户',
          isSystemAccount: true,
        },
      ],
    };

    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/province-area-reward-distribution?provinceCode=${provinceCode}&treeCount=${treeCount}`,
      );

      if (!response.ok) {
        this.logger.warn(`Failed to get province area reward distribution for province ${provinceCode}`);
        return defaultDistribution;
      }

      const result: AuthorizationServiceResponse<AreaRewardDistributionResult> = await response.json();

      if (!result.data?.distributions || result.data.distributions.length === 0) {
        this.logger.warn(`Empty province area distributions returned for province ${provinceCode}`);
        return defaultDistribution;
      }

      this.logger.debug(
        `getProvinceAreaRewardDistribution for provinceCode=${provinceCode}, treeCount=${treeCount}: ` +
        `distributions=${JSON.stringify(result.data.distributions)}`,
      );

      return result.data;
    } catch (error) {
      this.logger.error(`Error getting province area reward distribution:`, error);
      return defaultDistribution;
    }
  }

  async getCityTeamRewardDistribution(accountSequence: string, cityCode: string, treeCount: number): Promise<RewardDistribution> {
    const HEADQUARTERS_ACCOUNT_SEQUENCE = 'S0000000001';
    const defaultDistribution: RewardDistribution = {
      distributions: [
        {
          accountSequence: HEADQUARTERS_ACCOUNT_SEQUENCE,
          treeCount,
          reason: '服务调用失败，默认进总部社区',
        },
      ],
    };

    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/city-team-reward-distribution?accountSequence=${accountSequence}&cityCode=${cityCode}&treeCount=${treeCount}`,
      );

      if (!response.ok) {
        this.logger.warn(`Failed to get city team reward distribution for accountSequence ${accountSequence}, city ${cityCode}`);
        return defaultDistribution;
      }

      const result: AuthorizationServiceResponse<RewardDistributionResult> = await response.json();

      if (!result.data?.distributions || result.data.distributions.length === 0) {
        this.logger.warn(`Empty city team distributions returned for accountSequence ${accountSequence}`);
        return defaultDistribution;
      }

      this.logger.debug(
        `getCityTeamRewardDistribution for accountSequence=${accountSequence}, cityCode=${cityCode}, treeCount=${treeCount}: ` +
        `distributions=${JSON.stringify(result.data.distributions)}`,
      );

      return result.data;
    } catch (error) {
      this.logger.error(`Error getting city team reward distribution:`, error);
      return defaultDistribution;
    }
  }

  async getCityAreaRewardDistribution(cityCode: string, treeCount: number): Promise<AreaRewardDistribution> {
    // 系统市账户ID: 8 + cityCode (6位)
    const systemCityAccountId = `8${cityCode.padStart(6, '0')}`;
    const defaultDistribution: AreaRewardDistribution = {
      distributions: [
        {
          accountSequence: systemCityAccountId,
          treeCount,
          reason: '服务调用失败，默认进系统市账户',
          isSystemAccount: true,
        },
      ],
    };

    try {
      const response = await fetch(
        `${this.baseUrl}/api/v1/authorization/city-area-reward-distribution?cityCode=${cityCode}&treeCount=${treeCount}`,
      );

      if (!response.ok) {
        this.logger.warn(`Failed to get city area reward distribution for city ${cityCode}`);
        return defaultDistribution;
      }

      const result: AuthorizationServiceResponse<AreaRewardDistributionResult> = await response.json();

      if (!result.data?.distributions || result.data.distributions.length === 0) {
        this.logger.warn(`Empty city area distributions returned for city ${cityCode}`);
        return defaultDistribution;
      }

      this.logger.debug(
        `getCityAreaRewardDistribution for cityCode=${cityCode}, treeCount=${treeCount}: ` +
        `distributions=${JSON.stringify(result.data.distributions)}`,
      );

      return result.data;
    } catch (error) {
      this.logger.error(`Error getting city area reward distribution:`, error);
      return defaultDistribution;
    }
  }
}
