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

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

/**
 * @title RunMainnetUniV2CwusdcUsdcFlashRebalanceRemove
 * @notice Simulate or broadcast flash rebalance + LP remove on mainnet cWUSDC/USDC UniV2.
 *
 * Prerequisite: run plan-mainnet-cwusdc-usdc-univ2-flash-rebalance-remove.py and transfer LP
 * to the receiver (or set UNIV2_FLASH_PULL_LP=1 with prior LP approval to receiver).
 *
 * Env:
 *   PRIVATE_KEY
 *   ETHEREUM_MAINNET_RPC
 *   UNIV2_FLASH_REBALANCE_RECEIVER_MAINNET
 *   UNIV2_FLASH_REBALANCE_PLAN_JSON  optional path to planner JSON
 */
contract RunMainnetUniV2CwusdcUsdcFlashRebalanceRemove is Script {
    address internal constant DEFAULT_PAIR = 0xC28706F899266b36BC43cc072b3a921BDf2C48D9;
    address internal constant DEFAULT_ROUTER = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address internal constant DEFAULT_CW = 0x2de5F116bFcE3d0f922d9C8351e0c5Fc24b9284a;
    address internal constant DEFAULT_USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48;

    function run() external {
        uint256 pk = vm.envUint("PRIVATE_KEY");
        address receiver = vm.envAddress("UNIV2_FLASH_REBALANCE_RECEIVER_MAINNET");
        string memory planPath = vm.envOr(
            "UNIV2_FLASH_REBALANCE_PLAN_JSON",
            string("reports/status/mainnet-cwusdc-usdc-univ2-flash-rebalance-plan-latest.json")
        );

        (
            address pair,
            address router,
            address cw,
            address usdc,
            address lpHolder,
            address recipient,
            uint256 lpAmount,
            uint256 flashStableIn,
            uint256 minCwRebalance,
            uint256 minCwRemove,
            uint256 minStableRemove,
            uint256 cwToSell,
            uint256 minStableRepay
        ) = _loadPlan(planPath);

        pair = pair == address(0) ? DEFAULT_PAIR : pair;
        router = router == address(0) ? DEFAULT_ROUTER : router;
        cw = cw == address(0) ? DEFAULT_CW : cw;
        usdc = usdc == address(0) ? DEFAULT_USDC : usdc;

        console.log("receiver", receiver);
        console.log("pair", pair);
        console.log("lpHolder", lpHolder);
        console.log("lpAmount", lpAmount);
        console.log("flashStableIn", flashStableIn);
        console.log("receiverLpBefore", IERC20(pair).balanceOf(receiver));

        vm.startBroadcast(pk);
        if (vm.envOr("UNIV2_FLASH_PULL_LP", uint256(0)) == 1) {
            AaveUniV2CwStableRebalanceFlashReceiver(receiver).pullLpFrom(pair, lpHolder, lpAmount);
        }
        AaveUniV2CwStableRebalanceFlashReceiver.RebalanceRemoveParams memory p =
        AaveUniV2CwStableRebalanceFlashReceiver.RebalanceRemoveParams({
            router: router,
            pair: pair,
            cwToken: cw,
            stableToken: usdc,
            lpAmount: lpAmount,
            rebalanceStableIn: flashStableIn,
            minCwFromRebalance: minCwRebalance,
            minStableFromRemove: minStableRemove,
            minCwFromRemove: minCwRemove,
            cwToSellForRepay: cwToSell,
            minStableFromRepaySwap: minStableRepay,
            recipient: recipient
        });
        AaveUniV2CwStableRebalanceFlashReceiver(receiver).runRebalanceRemove(usdc, flashStableIn, p);
        vm.stopBroadcast();

        console.log("recipientStableAfter", IERC20(usdc).balanceOf(recipient));
        console.log("recipientCwAfter", IERC20(cw).balanceOf(recipient));
    }

    function _loadPlan(string memory path)
        internal
        view
        returns (
            address pair,
            address router,
            address cw,
            address usdc,
            address lpHolder,
            address recipient,
            uint256 lpAmount,
            uint256 flashStableIn,
            uint256 minCwRebalance,
            uint256 minCwRemove,
            uint256 minStableRemove,
            uint256 cwToSell,
            uint256 minStableRepay
        )
    {
        string memory json = vm.readFile(path);
        pair = vm.parseJsonAddress(json, ".pair");
        router = vm.parseJsonAddress(json, ".router");
        cw = vm.parseJsonAddress(json, ".cwToken");
        usdc = vm.parseJsonAddress(json, ".stableToken");
        lpHolder = vm.parseJsonAddress(json, ".lpHolder");
        recipient = vm.parseJsonAddress(json, ".recipient");
        lpAmount = vm.parseJsonUint(json, ".lpAmountRaw");
        flashStableIn = vm.parseJsonUint(json, ".flashLoan.stableBorrowRaw");
        minCwRebalance = vm.parseJsonUint(json, ".rebalanceSwap.minCwOutRaw");
        minCwRemove = vm.parseJsonUint(json, ".removeLiquidity.minCwOutRaw");
        minStableRemove = vm.parseJsonUint(json, ".removeLiquidity.minStableOutRaw");
        cwToSell = vm.parseJsonUint(json, ".repaySwap.cwToSellRaw");
        minStableRepay = vm.parseJsonUint(json, ".repaySwap.minStableOutRaw");
    }
}
