import { Injectable, Logger, HttpException, HttpStatus } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import axios, { AxiosInstance } from 'axios';

/**
 * Identity Service 客户端
 * 用于调用 identity-service 的 API
 */
@Injectable()
export class IdentityClientService {
  private readonly logger = new Logger(IdentityClientService.name);
  private readonly httpClient: AxiosInstance;

  constructor(private readonly configService: ConfigService) {
    const baseUrl = this.configService.get<string>('IDENTITY_SERVICE_URL', 'http://localhost:3000');

    this.httpClient = axios.create({
      baseURL: `${baseUrl}/api/v1`,
      timeout: 10000,
    });

    this.logger.log(`Identity client initialized: ${baseUrl}/api/v1`);
  }

  /**
   * 验证用户的 TOTP 码
   *
   * @param userId 用户 ID
   * @param totpCode TOTP 验证码
   * @param token JWT token (用于认证)
   * @returns 验证是否成功
   */
  async verifyTotp(userId: string, totpCode: string, token: string): Promise<boolean> {
    try {
      this.logger.log(`验证 TOTP: userId=${userId}`);

      const response = await this.httpClient.post(
        '/totp/verify',
        { code: totpCode },
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      // identity-service 响应格式: { success: true, data: { valid: true } }
      const valid = response.data?.data?.valid === true;
      this.logger.log(`TOTP 验证结果: userId=${userId}, valid=${valid}`);

      return valid;
    } catch (error: any) {
      this.logger.error(`TOTP 验证失败: userId=${userId}, error=${error.message}`);

      // 如果是 identity-service 返回的错误
      if (error.response) {
        const status = error.response.status;
        const message = error.response.data?.message || 'TOTP 验证失败';

        if (status === 400 || status === 401) {
          throw new HttpException(message, HttpStatus.BAD_REQUEST);
        }
      }

      // 网络错误或其他错误
      throw new HttpException('TOTP 验证服务不可用', HttpStatus.SERVICE_UNAVAILABLE);
    }
  }

  /**
   * 检查用户是否启用了 TOTP
   *
   * @param userId 用户 ID
   * @param token JWT token
   * @returns 是否启用 TOTP
   */
  async isTotpEnabled(userId: string, token: string): Promise<boolean> {
    try {
      this.logger.log(`检查 TOTP 状态: userId=${userId}`);

      const response = await this.httpClient.get('/totp/status', {
        headers: {
          Authorization: `Bearer ${token}`,
        },
      });

      // identity-service 响应格式: { success: true, data: { isEnabled: true } }
      const isEnabled = response.data?.data?.isEnabled === true;
      this.logger.log(`TOTP 状态: userId=${userId}, enabled=${isEnabled}`);

      return isEnabled;
    } catch (error: any) {
      this.logger.error(`获取 TOTP 状态失败: userId=${userId}, error=${error.message}`);

      // 如果获取状态失败，假设未启用 TOTP（允许操作继续）
      return false;
    }
  }

  /**
   * 发送提取验证短信
   *
   * @param userId 用户 ID
   * @param token JWT token
   */
  async sendWithdrawSmsCode(userId: string, token: string): Promise<void> {
    try {
      this.logger.log(`发送提取验证短信: userId=${userId}`);

      await this.httpClient.post(
        '/user/sms/send-withdraw-code',
        {},
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      this.logger.log(`发送提取验证短信成功: userId=${userId}`);
    } catch (error: any) {
      this.logger.error(`发送提取验证短信失败: userId=${userId}, error=${error.message}`);

      if (error.response) {
        const message = error.response.data?.message || '发送验证码失败';
        throw new HttpException(message, error.response.status || HttpStatus.BAD_REQUEST);
      }

      throw new HttpException('短信服务不可用', HttpStatus.SERVICE_UNAVAILABLE);
    }
  }

  /**
   * 验证提取短信验证码
   *
   * @param userId 用户 ID
   * @param smsCode 短信验证码
   * @param token JWT token
   * @returns 验证是否成功
   */
  async verifyWithdrawSmsCode(userId: string, smsCode: string, token: string): Promise<boolean> {
    try {
      this.logger.log(`验证提取短信验证码: userId=${userId}`);

      const response = await this.httpClient.post(
        '/user/sms/verify-withdraw-code',
        { code: smsCode },
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      this.logger.log(`提取短信验证码响应: userId=${userId}, status=${response.status}, data=${JSON.stringify(response.data)}`);
      // identity-service 响应格式: { success: true, data: { valid: true } }
      const valid = response.data?.data?.valid === true;
      this.logger.log(`提取短信验证码验证结果: userId=${userId}, valid=${valid}`);

      return valid;
    } catch (error: any) {
      this.logger.error(`验证提取短信验证码失败: userId=${userId}, error=${error.message}`);

      if (error.response) {
        const status = error.response.status;
        const message = error.response.data?.message || '验证码错误';

        if (status === 400 || status === 401) {
          throw new HttpException(message, HttpStatus.BAD_REQUEST);
        }
      }

      throw new HttpException('短信验证服务不可用', HttpStatus.SERVICE_UNAVAILABLE);
    }
  }

  /**
   * 验证用户登录密码
   *
   * @param userId 用户 ID
   * @param password 登录密码
   * @param token JWT token
   * @returns 验证是否成功
   */
  async verifyPassword(userId: string, password: string, token: string): Promise<boolean> {
    try {
      this.logger.log(`验证登录密码: userId=${userId}`);

      const response = await this.httpClient.post(
        '/user/verify-password',
        { password },
        {
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      // identity-service 响应格式: { success: true, data: { valid: true } }
      const valid = response.data?.data?.valid === true;
      this.logger.log(`登录密码验证结果: userId=${userId}, valid=${valid}`);

      return valid;
    } catch (error: any) {
      this.logger.error(`验证登录密码失败: userId=${userId}, error=${error.message}`);

      if (error.response) {
        const status = error.response.status;
        const message = error.response.data?.message || '密码验证失败';

        if (status === 400 || status === 401) {
          throw new HttpException(message, HttpStatus.BAD_REQUEST);
        }
      }

      throw new HttpException('密码验证服务不可用', HttpStatus.SERVICE_UNAVAILABLE);
    }
  }

  /**
   * 通过 accountSequence 查询区块链地址
   *
   * @param accountSequence 用户账户序列号 (如 D25121400005)
   * @param chainType 链类型 (KAVA, BSC)
   * @param token JWT token
   * @returns 区块链地址，如果找不到则返回 null
   */
  async resolveAccountSequenceToAddress(
    accountSequence: string,
    chainType: string,
    token: string,
  ): Promise<string | null> {
    try {
      this.logger.log(`解析 accountSequence: ${accountSequence}, chainType=${chainType}`);

      const response = await this.httpClient.get(
        `/user/users/resolve-address/${accountSequence}`,
        {
          params: { chainType },
          headers: {
            Authorization: `Bearer ${token}`,
          },
        },
      );

      // identity-service 响应格式: { success: true, data: { address: '0x...' } }
      const address = response.data?.data?.address;
      this.logger.log(`accountSequence 解析结果: ${accountSequence} -> ${address}`);

      return address || null;
    } catch (error: any) {
      this.logger.error(
        `解析 accountSequence 失败: ${accountSequence}, error=${error.message}`,
      );

      if (error.response?.status === 404) {
        return null;
      }

      throw new HttpException('无法解析充值ID', HttpStatus.SERVICE_UNAVAILABLE);
    }
  }

  /**
   * 通过 accountSequence 查询用户信息（内部调用，无需认证）
   * 用于系统账户转出时获取接收方信息
   *
   * @param accountSequence 用户账户序列号 (如 D25121400005)
   * @returns 用户信息，如果找不到则返回 null
   */
  async getUserInfoByAccountSequence(
    accountSequence: string,
  ): Promise<{
    accountSequence: string;
    userId: string;
    realName: string | null;
    walletAddress: string;
  } | null> {
    try {
      this.logger.log(`查询用户信息: accountSequence=${accountSequence}`);

      const response = await this.httpClient.get(
        `/user/internal/users/by-account-sequence/${accountSequence}`,
      );

      // identity-service 响应格式: { success: true, data: { found: true, ... } }
      const data = response.data?.data;
      if (!data?.found) {
        this.logger.debug(`未找到用户: ${accountSequence}`);
        return null;
      }

      this.logger.log(`用户信息: ${accountSequence} -> userId=${data.userId}, realName=${data.realName}`);
      return {
        accountSequence: data.accountSequence,
        userId: data.userId,
        realName: data.realName || null,
        walletAddress: data.walletAddress,
      };
    } catch (error: any) {
      this.logger.error(
        `查询用户信息失败: ${accountSequence}, error=${error.message}`,
      );

      if (error.response?.status === 404) {
        return null;
      }

      throw new HttpException('无法查询用户信息', HttpStatus.SERVICE_UNAVAILABLE);
    }
  }

  /**
   * 通过钱包地址查询用户信息（内部调用，无需认证）
   *
   * @param chainType 链类型 (KAVA, BSC)
   * @param address 钱包地址
   * @returns 用户信息，如果找不到则返回 null
   */
  async findUserByWalletAddress(
    chainType: string,
    address: string,
  ): Promise<{ accountSequence: string; userId: string } | null> {
    try {
      this.logger.log(`查询钱包地址对应用户: chainType=${chainType}, address=${address}`);

      const response = await this.httpClient.get(
        '/user/internal/users/by-wallet-address',
        {
          params: { chainType, address },
        },
      );

      // identity-service 响应格式: { success: true, data: { found: true, accountSequence: '...', userId: '...' } }
      const data = response.data?.data;
      if (!data?.found) {
        this.logger.debug(`未找到钱包地址对应用户: ${address}`);
        return null;
      }

      this.logger.log(`钱包地址对应用户: ${address} -> ${data.accountSequence}`);
      return {
        accountSequence: data.accountSequence,
        userId: data.userId,
      };
    } catch (error: any) {
      this.logger.error(
        `查询钱包地址对应用户失败: ${address}, error=${error.message}`,
      );

      // 查询失败时返回 null，不影响正常流程
      return null;
    }
  }
}
