import { Injectable, Logger } from '@nestjs/common';
import { C2cOrderRepository, C2cOrderEntity } from '../../infrastructure/persistence/repositories/c2c-order.repository';
import { TradingAccountRepository } from '../../infrastructure/persistence/repositories/trading-account.repository';
import { BlockchainClient } from '../../infrastructure/blockchain/blockchain.client';
import { IdentityClient } from '../../infrastructure/identity/identity.client';
import { RedisService } from '../../infrastructure/redis/redis.service';
import { PaymentProofService } from './payment-proof.service';
import Decimal from 'decimal.js';

/**
 * C2C Bot 服务
 * 自动购买用户发布的卖单，并通过 dUSDT 支付
 */
@Injectable()
export class C2cBotService {
  private readonly logger = new Logger(C2cBotService.name);

  constructor(
    private readonly c2cOrderRepository: C2cOrderRepository,
    private readonly tradingAccountRepository: TradingAccountRepository,
    private readonly blockchainClient: BlockchainClient,
    private readonly identityClient: IdentityClient,
    private readonly redis: RedisService,
    private readonly paymentProofService: PaymentProofService,
  ) {}

  /**
   * 处理单个卖单
   * @param order 卖单
   */
  async purchaseOrder(order: C2cOrderEntity): Promise<boolean> {
    const lockKey = `c2c:bot:order:${order.orderNo}`;
    const lockValue = await this.redis.acquireLock(lockKey, 60); // 60秒锁
    if (!lockValue) {
      this.logger.debug(`Order ${order.orderNo} is being processed by another instance`);
      return false;
    }

    try {
      this.logger.log(`[BOT] Processing order ${order.orderNo}`);
      this.logger.log(`[BOT] Seller: ${order.makerAccountSequence}`);
      this.logger.log(`[BOT] Amount: ${order.totalAmount}`);

      // 1. 获取卖家的 Kava 地址
      const kavaAddress = await this.identityClient.getUserKavaAddress(order.makerAccountSequence);
      if (!kavaAddress) {
        this.logger.error(`[BOT] Seller ${order.makerAccountSequence} has no Kava address`);
        return false;
      }
      this.logger.log(`[BOT] Seller Kava address: ${kavaAddress}`);

      // 2. 先扣减卖家积分值余额（可逆的DB操作，放在不可逆的链上转账之前）
      const paymentAmount = order.totalAmount;
      await this.deductSellerBalance(order.makerAccountSequence, paymentAmount);
      this.logger.log(`[BOT] Deducted seller balance, proceeding with on-chain transfer`);

      // 3. 调用 mining-blockchain-service 转账 dUSDT（不可逆）
      let transferResult;
      try {
        transferResult = await this.blockchainClient.transferDusdt(kavaAddress, paymentAmount);
      } catch (error: any) {
        this.logger.error(`[BOT] Transfer exception: ${error.message}, restoring seller balance`);
        await this.restoreSellerBalance(order.makerAccountSequence, paymentAmount);
        return false;
      }

      if (!transferResult.success) {
        this.logger.error(`[BOT] Transfer failed: ${transferResult.error}, restoring seller balance`);
        await this.restoreSellerBalance(order.makerAccountSequence, paymentAmount);
        return false;
      }

      this.logger.log(`[BOT] Transfer successful: txHash=${transferResult.txHash}`);

      // 4. 更新订单状态
      await this.c2cOrderRepository.updateBotPurchase(order.orderNo, {
        sellerKavaAddress: kavaAddress,
        paymentTxHash: transferResult.txHash!,
      });

      // 5. 生成付款水单图片并更新订单（失败不影响订单本身）
      try {
        const proofUrl = await this.paymentProofService.generateProofImage({
          orderNo: order.orderNo,
          amount: paymentAmount,
          txHash: transferResult.txHash!,
          sellerId: order.makerAccountSequence,
          sellerAddress: kavaAddress,
          completedAt: new Date(),
        });
        await this.c2cOrderRepository.updatePaymentProof(order.orderNo, proofUrl);
        this.logger.log(`[BOT] Payment proof generated: ${proofUrl}`);
      } catch (proofError: any) {
        this.logger.warn(`[BOT] Failed to generate payment proof for ${order.orderNo}: ${proofError.message}`);
      }

      this.logger.log(`[BOT] Order ${order.orderNo} completed successfully`);
      return true;
    } catch (error: any) {
      this.logger.error(`[BOT] Error processing order ${order.orderNo}: ${error.message}`);
      return false;
    } finally {
      await this.redis.releaseLock(lockKey, lockValue);
    }
  }

  /**
   * 扣减卖家的积分值余额
   */
  private async deductSellerBalance(accountSequence: string, amount: string): Promise<void> {
    const account = await this.tradingAccountRepository.findByAccountSequence(accountSequence);
    if (!account) {
      throw new Error(`Trading account ${accountSequence} not found`);
    }

    const amountDecimal = new Decimal(amount);
    const currentBalance = new Decimal(account.cashBalance.value);

    if (currentBalance.lessThan(amountDecimal)) {
      throw new Error(`Insufficient cash balance for ${accountSequence}`);
    }

    await this.tradingAccountRepository.updateCashBalance(
      accountSequence,
      amountDecimal.negated().toString(),
    );

    this.logger.log(`[BOT] Deducted ${amount} from ${accountSequence}'s cash balance`);
  }

  /**
   * 回补卖家的积分值余额（链上转账失败时的补偿操作）
   */
  private async restoreSellerBalance(accountSequence: string, amount: string): Promise<void> {
    try {
      await this.tradingAccountRepository.updateCashBalance(
        accountSequence,
        amount, // 正数，加回余额
      );
      this.logger.log(`[BOT] Restored ${amount} to ${accountSequence}'s cash balance`);
    } catch (error: any) {
      // 回补失败是严重问题，必须告警
      this.logger.error(`[BOT] CRITICAL: Failed to restore ${amount} to ${accountSequence}: ${error.message}`);
    }
  }

  /**
   * 检查 Bot 服务是否可用
   */
  async isAvailable(): Promise<boolean> {
    return await this.blockchainClient.isAvailable();
  }

  /**
   * 获取热钱包余额
   */
  async getHotWalletBalance(): Promise<string | null> {
    const balance = await this.blockchainClient.getHotWalletBalance();
    return balance?.balance || null;
  }
}
