// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {Script, console} from "forge-std/Script.sol";
import {DODOPMMIntegration} from "../../contracts/dex/DODOPMMIntegration.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
 * @title AddLiquidityPMMPoolsChain138
 * @notice Add liquidity to the canonical DODO PMM pools on Chain 138, including the stable/WETH lanes.
 * @dev Env: PRIVATE_KEY, RPC_URL_138, DODO_PMM_INTEGRATION_ADDRESS (or DODO_PMM_INTEGRATION),
 *      POOL_CUSDTCUSDC, POOL_CUSDTUSDT, POOL_CUSDCUSDC,
 *      optional POOL_CUSDTWETH, POOL_CUSDCWETH, POOL_CEURTWETH,
 *      ADD_LIQUIDITY_BASE_AMOUNT, ADD_LIQUIDITY_QUOTE_AMOUNT (e.g. 1000000e6 for 1M units, 6 decimals).
 *      Optional: ADD_LIQUIDITY_CUSDTCUSDC_BASE, ADD_LIQUIDITY_CUSDTCUSDC_QUOTE, etc. for per-pool amounts.
 *      Optional: NEXT_NONCE — set to pending nonce (e.g. after mints) to avoid -32001 "Nonce too low" on broadcast.
 */
contract AddLiquidityPMMPoolsChain138 is Script {
    function run() external {
        uint256 pk = vm.envUint("PRIVATE_KEY");
        address deployer = vm.addr(pk);
        address integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION");
        if (integrationAddr == address(0)) integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION_ADDRESS");
        require(integrationAddr != address(0), "DODO_PMM_INTEGRATION not set");

        // Use explicit nonce when set (e.g. after mints in same session) to avoid -32001 "Nonce too low"
        uint64 nextNonce = uint64(vm.envOr("NEXT_NONCE", uint256(0)));
        if (nextNonce > 0) {
            vm.setNonce(deployer, nextNonce);
        }

        address poolCusdtCusdc = vm.envOr("POOL_CUSDTCUSDC", address(0));
        address poolCusdtUsdt = vm.envOr("POOL_CUSDTUSDT", address(0));
        address poolCusdcUsdc = vm.envOr("POOL_CUSDCUSDC", address(0));
        address poolCusdtWeth = vm.envOr("POOL_CUSDTWETH", address(0));
        address poolCusdcWeth = vm.envOr("POOL_CUSDCWETH", address(0));
        address poolCeurtWeth = vm.envOr("POOL_CEURTWETH", address(0));

        uint256 defaultBase = vm.envOr("ADD_LIQUIDITY_BASE_AMOUNT", uint256(0));
        uint256 defaultQuote = vm.envOr("ADD_LIQUIDITY_QUOTE_AMOUNT", uint256(0));

        DODOPMMIntegration integration = DODOPMMIntegration(integrationAddr);
        address cusdt = integration.compliantUSDT();
        address cusdc = integration.compliantUSDC();
        address usdt = integration.officialUSDT();
        address usdc = integration.officialUSDC();
        address ceurt = vm.envOr("CEURT_ADDRESS_138", address(0xdf4b71c61E5912712C1Bdd451416B9aC26949d72));
        address weth = vm.envOr("WETH9_ADDRESS_138", vm.envOr("WETH_ADDRESS_138", address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2)));

        // On Chain 138, cUSDT/USDT and cUSDC/USDC should point at live local mirror quote tokens.
        // If the configured quote-side addresses have no code on 138, skip those pools to avoid "call to non-contract".
        bool skipOfficialPools = block.chainid == 138 && (
            !_isContract(usdt) || !_isContract(usdc)
        );

        vm.startBroadcast(pk);

        if (poolCusdtCusdc != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
            uint256 b = vm.envOr("ADD_LIQUIDITY_CUSDTCUSDC_BASE", defaultBase);
            uint256 q = vm.envOr("ADD_LIQUIDITY_CUSDTCUSDC_QUOTE", defaultQuote);
            if (b > 0 && q > 0) {
                _approveAndAdd(integration, cusdt, cusdc, poolCusdtCusdc, b, q);
                console.log("Added liquidity to cUSDT/cUSDC pool:", poolCusdtCusdc);
            }
        }
        if (!skipOfficialPools && poolCusdtUsdt != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
            uint256 b = vm.envOr("ADD_LIQUIDITY_CUSDTUSDT_BASE", defaultBase);
            uint256 q = vm.envOr("ADD_LIQUIDITY_CUSDTUSDT_QUOTE", defaultQuote);
            if (b > 0 && q > 0) {
                _approveAndAdd(integration, cusdt, usdt, poolCusdtUsdt, b, q);
                console.log("Added liquidity to cUSDT/USDT pool:", poolCusdtUsdt);
            }
        }
        if (!skipOfficialPools && poolCusdcUsdc != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
            uint256 b = vm.envOr("ADD_LIQUIDITY_CUSDCUSDC_BASE", defaultBase);
            uint256 q = vm.envOr("ADD_LIQUIDITY_CUSDCUSDC_QUOTE", defaultQuote);
            if (b > 0 && q > 0) {
                _approveAndAdd(integration, cusdc, usdc, poolCusdcUsdc, b, q);
                console.log("Added liquidity to cUSDC/USDC pool:", poolCusdcUsdc);
            }
        }
        if (poolCusdtWeth != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
            uint256 b = vm.envOr("ADD_LIQUIDITY_CUSDTWETH_BASE", defaultBase);
            uint256 q = vm.envOr("ADD_LIQUIDITY_CUSDTWETH_QUOTE", defaultQuote);
            if (b > 0 && q > 0) {
                _approveAndAdd(integration, cusdt, weth, poolCusdtWeth, b, q);
                console.log("Added liquidity to cUSDT/WETH pool:", poolCusdtWeth);
            }
        }
        if (poolCusdcWeth != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
            uint256 b = vm.envOr("ADD_LIQUIDITY_CUSDCWETH_BASE", defaultBase);
            uint256 q = vm.envOr("ADD_LIQUIDITY_CUSDCWETH_QUOTE", defaultQuote);
            if (b > 0 && q > 0) {
                _approveAndAdd(integration, cusdc, weth, poolCusdcWeth, b, q);
                console.log("Added liquidity to cUSDC/WETH pool:", poolCusdcWeth);
            }
        }
        if (poolCeurtWeth != address(0) && (defaultBase > 0 || defaultQuote > 0)) {
            uint256 b = vm.envOr("ADD_LIQUIDITY_CEURTWETH_BASE", defaultBase);
            uint256 q = vm.envOr("ADD_LIQUIDITY_CEURTWETH_QUOTE", defaultQuote);
            if (b > 0 && q > 0) {
                _approveAndAdd(integration, ceurt, weth, poolCeurtWeth, b, q);
                console.log("Added liquidity to cEURT/WETH pool:", poolCeurtWeth);
            }
        }

        vm.stopBroadcast();
    }

    function _isContract(address account) internal view returns (bool) {
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    function _approveAndAdd(
        DODOPMMIntegration integration,
        address baseToken,
        address quoteToken,
        address pool,
        uint256 baseAmount,
        uint256 quoteAmount
    ) internal {
        IERC20(baseToken).approve(address(integration), type(uint256).max);
        IERC20(quoteToken).approve(address(integration), type(uint256).max);
        integration.addLiquidity(pool, baseAmount, quoteAmount);
    }
}
