import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { HttpService } from '@nestjs/axios';
import { firstValueFrom } from 'rxjs';

/**
 * 用户详情信息响应
 */
export interface UserDetailInfo {
  userId: string;
  accountSequence: string;
  nickname: string;
  avatarUrl?: string;
  phoneNumber?: string;
  email?: string;
  registeredAt: string;
  inviterSequence?: string;
  kycStatus: string;
  realName?: string;
  idCardNumber?: string;
}

/**
 * 用户 KYC 信息（用于合同签署）
 */
export interface UserKycInfo {
  phoneNumber?: string;
  realName?: string;
  idCardNumber?: string;
}

/**
 * HTTP 重试配置
 */
interface RetryConfig {
  maxRetries: number;
  baseDelayMs: number;
  maxDelayMs: number;
}

const DEFAULT_RETRY_CONFIG: RetryConfig = {
  maxRetries: 3,
  baseDelayMs: 500,
  maxDelayMs: 5000,
};

/**
 * Identity Service 客户端
 * 用于获取用户信息和 KYC 数据
 */
@Injectable()
export class IdentityServiceClient {
  private readonly logger = new Logger(IdentityServiceClient.name);
  private readonly baseUrl: string;
  private readonly retryConfig: RetryConfig;

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

  /**
   * 带重试的 HTTP 请求包装器
   */
  private async withRetry<T>(
    operation: string,
    fn: () => Promise<T>,
    config: RetryConfig = this.retryConfig,
  ): Promise<T> {
    let lastError: Error | undefined;

    for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
      try {
        return await fn();
      } catch (error: unknown) {
        lastError = error as Error;

        const shouldRetry = this.shouldRetry(error, attempt, config.maxRetries);
        if (!shouldRetry) {
          throw error;
        }

        const delay = this.calculateBackoffDelay(attempt, config);
        this.logger.warn(
          `${operation} failed (attempt ${attempt + 1}/${config.maxRetries + 1}), ` +
            `retrying in ${delay}ms: ${(error as Error).message}`,
        );

        await this.delay(delay);
      }
    }

    throw lastError;
  }

  private shouldRetry(
    error: unknown,
    attempt: number,
    maxRetries: number,
  ): boolean {
    if (attempt >= maxRetries) {
      return false;
    }

    const axiosError = error as { response?: { status?: number }; code?: string };

    // 网络错误 - 应该重试
    if (!axiosError.response) {
      const retryableCodes = ['ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT', 'ENOTFOUND'];
      if (axiosError.code && retryableCodes.includes(axiosError.code)) {
        return true;
      }
      if ((error as Error).message?.includes('timeout')) {
        return true;
      }
      return true;
    }

    // 5xx 服务器错误 - 应该重试
    if (axiosError.response.status && axiosError.response.status >= 500) {
      return true;
    }

    // 429 Too Many Requests - 可以重试
    if (axiosError.response.status === 429) {
      return true;
    }

    return false;
  }

  private calculateBackoffDelay(attempt: number, config: RetryConfig): number {
    const exponentialDelay = config.baseDelayMs * Math.pow(2, attempt);
    const jitter = Math.random() * config.baseDelayMs * 0.5;
    return Math.min(exponentialDelay + jitter, config.maxDelayMs);
  }

  private delay(ms: number): Promise<void> {
    return new Promise((resolve) => setTimeout(resolve, ms));
  }

  /**
   * 根据 accountSequence 获取用户详情
   */
  async getUserDetailBySequence(accountSequence: string): Promise<UserDetailInfo | null> {
    try {
      return await this.withRetry(
        `getUserDetailBySequence(${accountSequence})`,
        async () => {
          const response = await firstValueFrom(
            this.httpService.get<{ success: boolean; data: UserDetailInfo }>(
              `${this.baseUrl}/api/v1/internal/users/${accountSequence}/detail`,
            ),
          );
          // identity-service 的响应被 TransformInterceptor 包装为 { success, data }
          return response.data?.data || null;
        },
      );
    } catch (error) {
      this.logger.error(`Failed to get user detail for accountSequence ${accountSequence}:`, error);
      return null;
    }
  }

  /**
   * 获取用户 KYC 信息用于合同签署
   * 只有 KYC 状态为 VERIFIED 的用户才能签署合同
   * @returns KYC 信息，如果未认证则返回 null
   */
  async getUserKycInfo(accountSequence: string): Promise<UserKycInfo | null> {
    const userDetail = await this.getUserDetailBySequence(accountSequence);

    if (!userDetail) {
      this.logger.warn(`User not found for accountSequence: ${accountSequence}`);
      return null;
    }

    // 检查 KYC 状态 - 实名认证通过即可签署合同
    // 接受的状态: REAL_NAME_VERIFIED, FACE_VERIFIED, KYC_VERIFIED, COMPLETED, VERIFIED
    const validKycStatuses = ['REAL_NAME_VERIFIED', 'FACE_VERIFIED', 'KYC_VERIFIED', 'COMPLETED', 'VERIFIED'];
    if (!validKycStatuses.includes(userDetail.kycStatus)) {
      this.logger.warn(
        `User ${accountSequence} KYC status is ${userDetail.kycStatus}, not in ${validKycStatuses.join('/')}. Cannot create contract.`,
      );
      return null;
    }

    return {
      phoneNumber: userDetail.phoneNumber,
      realName: userDetail.realName,
      idCardNumber: userDetail.idCardNumber,
    };
  }
}
