import { ethers } from "hardhat";
import { Lending } from "../../typechain-types";

/**
 * 购买清算抵押品脚本
 * 
 * 环境变量:
 * - LENDING_ADDRESS: Lending 合约地址
 * - ASSET_ADDRESS: 抵押品资产地址
 * - BASE_AMOUNT (可选): 愿意支付的最大金额，默认 100
 * - SLIPPAGE (可选): 滑点容忍度 (1-5)，默认 2
 */
async function main() {
  // ==================== 配置 ====================
  const LENDING_ADDRESS = process.env.LENDING_ADDRESS;
  const ASSET_ADDRESS = process.env.ASSET_ADDRESS;
  const BASE_AMOUNT_INPUT = process.env.BASE_AMOUNT || "100";
  const SLIPPAGE_PERCENT = parseInt(process.env.SLIPPAGE || "2");

  // 参数验证
  if (!LENDING_ADDRESS || LENDING_ADDRESS === "0x...") {
    throw new Error("❌ 请设置 LENDING_ADDRESS 环境变量");
  }
  if (!ASSET_ADDRESS || ASSET_ADDRESS === "0x...") {
    throw new Error("❌ 请设置 ASSET_ADDRESS 环境变量");
  }

  const SLIPPAGE = SLIPPAGE_PERCENT / 100; // 转换为小数

  console.log("==================== 购买清算抵押品 ====================");
  console.log(`Lending 合约: ${LENDING_ADDRESS}`);
  console.log(`抵押品地址: ${ASSET_ADDRESS}`);
  console.log(`最大支付金额: ${BASE_AMOUNT_INPUT} USDC`);
  console.log(`滑点容忍度: ${SLIPPAGE_PERCENT}%\n`);

  // ==================== 初始化 ====================
  const lending = await ethers.getContractAt("Lending", LENDING_ADDRESS) as unknown as Lending;
  const [buyer] = await ethers.getSigners();
  const baseToken = await lending.baseToken();
  const base = await ethers.getContractAt("IERC20Metadata", baseToken);
  const baseDecimals = await base.decimals();
  
  const BASE_AMOUNT = ethers.parseUnits(BASE_AMOUNT_INPUT, baseDecimals);

  console.log(`买家地址: ${buyer.address}\n`);

  // ==================== 前置检查 ====================
  console.log("📊 检查系统状态...");
  
  // 1. 检查储备金状态
  const reserves = await lending.getReserves();
  const targetReserves = await lending.targetReserves();
  console.log(`✓ 当前储备金: ${ethers.formatUnits(reserves, baseDecimals)} USDC`);
  console.log(`✓ 目标储备金: ${ethers.formatUnits(targetReserves, baseDecimals)} USDC`);

  if (reserves >= targetReserves) {
    throw new Error("❌ 储备金充足，当前无法购买抵押品");
  }

  // 2. 检查抵押品储备
  const collateralReserve = await lending.getCollateralReserves(ASSET_ADDRESS);
  if (collateralReserve === 0n) {
    throw new Error("❌ 该抵押品储备为空，无法购买");
  }
  const asset = await ethers.getContractAt("IERC20Metadata", ASSET_ADDRESS);
  const assetDecimals = await asset.decimals();
  console.log(`✓ 抵押品储备: ${ethers.formatUnits(collateralReserve, assetDecimals)} 代币\n`);

  // 3. 检查买家余额
  const buyerBalance = await base.balanceOf(buyer.address);
  console.log(`💰 买家余额: ${ethers.formatUnits(buyerBalance, baseDecimals)} USDC`);
  if (buyerBalance < BASE_AMOUNT) {
    throw new Error(`❌ 余额不足。需要: ${ethers.formatUnits(BASE_AMOUNT, baseDecimals)} USDC，当前: ${ethers.formatUnits(buyerBalance, baseDecimals)} USDC`);
  }

  // ==================== 获取购买信息 ====================
  console.log("\n📋 计算购买详情...");
  const info = await getBuyCollateralInfo(lending, ASSET_ADDRESS, BASE_AMOUNT, SLIPPAGE);

  console.log(`✓ 预期购买: ${ethers.formatUnits(info.expectedAmount, assetDecimals)} 代币`);
  console.log(`✓ 实际购买: ${ethers.formatUnits(info.actualAmount, assetDecimals)} 代币`);
  console.log(`✓ 最小接受: ${ethers.formatUnits(info.minAmount, assetDecimals)} 代币`);
  
  if (info.isLimited) {
    console.log(`\n⚠️  储备不足，购买量已调整:`);
    console.log(`  原计划支付: ${ethers.formatUnits(info.baseAmount, baseDecimals)} USDC`);
    console.log(`  实际约支付: ${ethers.formatUnits(info.actualBaseAmount, baseDecimals)} USDC`);
    console.log(`  节省约: ${ethers.formatUnits(info.baseAmount - info.actualBaseAmount, baseDecimals)} USDC`);
  }

  // ==================== 授权检查 ====================
  console.log("\n🔐 检查授权...");
  const allowance = await base.allowance(buyer.address, LENDING_ADDRESS);
  
  if (allowance < BASE_AMOUNT) {
    console.log(`当前授权: ${ethers.formatUnits(allowance, baseDecimals)} USDC (不足)`);
    console.log("正在授权...");
    const approveTx = await base.approve(LENDING_ADDRESS, ethers.MaxUint256);
    await approveTx.wait();
    console.log("✅ 授权成功");
  } else {
    console.log("✓ 授权充足");
  }

  // ==================== 执行购买 ====================
  console.log("\n💸 执行购买交易...");
  const tx = await lending.buyCollateral(
    ASSET_ADDRESS,
    info.minAmount,
    BASE_AMOUNT,
    buyer.address
  );

  console.log(`交易已提交: ${tx.hash}`);
  console.log("等待确认...");
  
  const receipt = await tx.wait();
  console.log(`✅ 交易确认! Gas 消耗: ${receipt?.gasUsed.toString()}\n`);

  // ==================== 解析结果 ====================
  const buyEvent = receipt?.logs.find((log: any) => {
    try {
      return lending.interface.parseLog(log)?.name === "BuyCollateral";
    } catch {
      return false;
    }
  });

  if (buyEvent) {
    const parsedEvent = lending.interface.parseLog(buyEvent);
    const paidAmount = parsedEvent?.args.baseAmount;
    const receivedAmount = parsedEvent?.args.collateralAmount;
    
    console.log("==================== 交易结果 ====================");
    console.log(`✓ 实际支付: ${ethers.formatUnits(paidAmount, baseDecimals)} USDC`);
    console.log(`✓ 实际获得: ${ethers.formatUnits(receivedAmount, assetDecimals)} 代币`);
    console.log(`✓ 购买者: ${parsedEvent?.args.buyer}`);
    console.log(`✓ 接收地址: ${buyer.address}`);
    
    // 计算实际单价和折扣信息
    // 实际单价 = 支付金额 / 获得数量
    const actualPricePerToken = (paidAmount * ethers.parseUnits("1", assetDecimals)) / receivedAmount;
    
    // 计算正常市场价（使用 quoteCollateral 反推）
    // 如果用相同的 baseAmount 在市场价购买，能买到多少代币
    const marketAmount = await lending.quoteCollateral(ASSET_ADDRESS, paidAmount);
    
    console.log(`\n💰 折扣购买说明:`);
    console.log(`✓ 实际单价: ${ethers.formatUnits(actualPricePerToken, baseDecimals)} USDC/代币`);
    
    // 只有当实际购买量大于市场价购买量时才显示折扣
    if (receivedAmount > marketAmount) {
      const discount = ((receivedAmount - marketAmount) * 10000n) / marketAmount;
      const saved = actualPricePerToken * marketAmount / ethers.parseUnits("1", assetDecimals) - paidAmount;
      
      console.log(`✓ 市场价可购买: ${ethers.formatUnits(marketAmount, assetDecimals)} 代币`);
      console.log(`✓ 折扣多得: ${ethers.formatUnits(receivedAmount - marketAmount, assetDecimals)} 代币 (${Number(discount) / 100}%)`);
      console.log(`✓ 相当于节省: ${ethers.formatUnits(saved, baseDecimals)} USDC`);
    } else {
      console.log(`ℹ️  这是清算抵押品的折扣购买，价格低于市场价`);
    }
    console.log("===================================================");
  }

  // ==================== 更新后状态 ====================
  console.log("\n📊 购买后状态:");
  const newBalance = await base.balanceOf(buyer.address);
  const newAssetBalance = await asset.balanceOf(buyer.address);
  console.log(`买家 USDC 余额: ${ethers.formatUnits(newBalance, baseDecimals)} USDC`);
  console.log(`买家抵押品余额: ${ethers.formatUnits(newAssetBalance, assetDecimals)} 代币`);
  
  console.log("\n✅ 购买完成!");
}

main()
  .then(() => process.exit(0))
  .catch((error) => {
    console.error("\n❌ 执行失败:", error.message || error);
    process.exit(1);
  });

  /**
 * 获取详细的购买信息
 */
export async function getBuyCollateralInfo(
  lendingContract: Lending,
  asset: string,
  baseAmount: bigint,
  slippageTolerance: number = 0.01
) {
  const expectedAmount = await lendingContract.quoteCollateral(asset, baseAmount);
  const availableReserve = await lendingContract.getCollateralReserves(asset);
  const actualAmount = expectedAmount < availableReserve ? expectedAmount : availableReserve;

  const slippageMultiplier = BigInt(Math.floor((1 - slippageTolerance) * 1e18));
  const minAmount = (actualAmount * slippageMultiplier) / BigInt(1e18);

  // 估算实际支付金额（基于实际购买量）
  const actualBaseAmount = actualAmount < expectedAmount
    ? (baseAmount * actualAmount) / expectedAmount  // 按比例计算
    : baseAmount;

  return {
    expectedAmount,           // 理想情况下可购买的数量
    availableReserve,         // 协议可用储备
    actualAmount,             // 实际可购买的数量（限制后）
    minAmount,                // 应用滑点保护后的最小值
    baseAmount,               // 用户愿意支付的最大金额
    actualBaseAmount,         // 实际需要支付的金额（可能更少）
    isLimited: actualAmount < expectedAmount,  // 是否受储备限制
  };
}