import { ethers, upgrades } from "hardhat";
import * as fs from "fs";
import * as path from "path";

/**
 * 部署 Lending 借贷池系统
 * 包含：LendingFactory, Configurator, Lending 实现和代理
 */
async function main() {
    const [deployer] = await ethers.getSigners();
    console.log("\n==========================================");
    console.log("📦 部署 Lending 借贷池系统");
    console.log("==========================================");
    console.log("部署账户:", deployer.address);
    console.log("账户余额:", ethers.formatEther(await ethers.provider.getBalance(deployer.address)), "ETH\n");

    const deployments: any = {};

    // ========== 第一阶段：部署工厂合约 ==========
    console.log("📦 Phase 1: 部署 LendingFactory...");
    const LendingFactory = await ethers.getContractFactory("LendingFactory");
    const lendingFactory = await LendingFactory.deploy();
    await lendingFactory.waitForDeployment();
    const lendingFactoryAddress = await lendingFactory.getAddress();
    console.log("✅ LendingFactory 已部署:", lendingFactoryAddress);
    deployments.lendingFactory = lendingFactoryAddress;

    // ========== 第二阶段：部署 Configurator ==========
    console.log("\n📦 Phase 2: 部署 Configurator (UUPS 代理)...");
    const Configurator = await ethers.getContractFactory("Configurator");
    
    // 使用 upgrades 插件部署 UUPS 代理
    const configurator = await upgrades.deployProxy(
        Configurator,
        [],
        {
            kind: "uups",
            initializer: "initialize"
        }
    );
    await configurator.waitForDeployment();
    
    const configuratorProxyAddress = await configurator.getAddress();
    console.log("✅ Configurator Proxy:", configuratorProxyAddress);
    deployments.configuratorProxy = configuratorProxyAddress;
    
    // 获取实现合约地址
    const configuratorImplAddress = await upgrades.erc1967.getImplementationAddress(configuratorProxyAddress);
    console.log("✅ Configurator Implementation:", configuratorImplAddress);
    deployments.configuratorImpl = configuratorImplAddress;
    
    console.log("✅ Configurator Owner:", await configurator.owner());

    // ========== 第三阶段：部署 Lending 实现合约 ==========
    console.log("\n📦 Phase 3: 通过工厂部署 Lending 实现合约...");
    const deployTx = await lendingFactory.deploy();
    const deployReceipt = await deployTx.wait();
    
    // 使用 logs 和 interface.parseLog 解析事件
    let lendingImplAddress;
    for (const log of deployReceipt.logs) {
        try {
            const parsedLog = lendingFactory.interface.parseLog({
                topics: [...log.topics],
                data: log.data
            });
            if (parsedLog && parsedLog.name === 'LendingDeployed') {
                lendingImplAddress = parsedLog.args.lending;
                break;
            }
        } catch (e) {
            // 忽略无法解析的日志
            continue;
        }
    }
    
    console.log("✅ Lending Implementation:", lendingImplAddress);
    deployments.lendingImpl = lendingImplAddress;

    // ========== 第四阶段：准备部署 Lending 代理 ==========
    console.log("\n📦 Phase 4: 准备部署 Lending 代理（需要先配置参数）");
    console.log("⚠️  请运行配置脚本 08-configureLending.ts 来完成配置和代理部署");

    // ========== 保存部署信息 ==========
    const deploymentsPath = path.join(__dirname, "../../deployments-lending.json");
    const existingDeployments = fs.existsSync(deploymentsPath) 
        ? JSON.parse(fs.readFileSync(deploymentsPath, "utf-8")) 
        : {};
    
    const network = await ethers.provider.getNetwork();
    const chainId = network.chainId.toString();
    existingDeployments[chainId] = {
        ...existingDeployments[chainId],
        ...deployments,
        timestamp: new Date().toISOString(),
        deployer: deployer.address
    };
    
    fs.writeFileSync(deploymentsPath, JSON.stringify(existingDeployments, null, 2));
    console.log("\n💾 部署信息已保存到:", deploymentsPath);

    // ========== 部署总结 ==========
    console.log("\n🎉 部署总结:");
    console.log("=====================================");
    console.log("LendingFactory:            ", deployments.lendingFactory);
    console.log("Configurator (Proxy):      ", deployments.configuratorProxy);
    console.log("Configurator (Impl):       ", deployments.configuratorImpl);
    console.log("Lending (Impl):            ", deployments.lendingImpl);
    console.log("=====================================\n");
}

main()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });

