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

import {Script, stdJson, console} from "forge-std/Script.sol";
import {DODOPMMIntegration} from "../../contracts/dex/DODOPMMIntegration.sol";
import {DODOPMMProvider} from "../../contracts/liquidity/providers/DODOPMMProvider.sol";

/**
 * @title ImportProviderPoolsToIntegration
 * @notice Import provider-known pools into DODOPMMIntegration using the desired-state JSON.
 * @dev This is the migration path for stale provider-only pools that already exist as DODO pool
 *      contracts but are missing from integration.pools / allPools / poolConfigs.
 *
 * Required env:
 * - PRIVATE_KEY
 * - DODO_PMM_INTEGRATION_ADDRESS (or DODO_PMM_INTEGRATION)
 * - DODO_PMM_PROVIDER_ADDRESS (or DODO_PMM_PROVIDER) for target provider compatibility
 *
 * Optional env:
 * - DODO_PMM_PROVIDER_SOURCE_ADDRESS (or DODO_PMM_PROVIDER_SOURCE) to read from an existing provider
 * - POOL_CONFIG_JSON (defaults to smom-dbis-138/config/chain138-pmm-pools.json)
 * - LP_FEE_RATE / INITIAL_PRICE / K_FACTOR / ENABLE_TWAP to override JSON defaults
 */
contract ImportProviderPoolsToIntegration is Script {
    using stdJson for string;

    string internal constant DEFAULT_CONFIG_PATH = "config/chain138-pmm-pools.json";

    function run() external {
        uint256 pk = vm.envUint("PRIVATE_KEY");
        address integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION_ADDRESS");
        if (integrationAddr == address(0)) integrationAddr = vm.envAddress("DODO_PMM_INTEGRATION");
        address providerAddr = vm.envAddress("DODO_PMM_PROVIDER_ADDRESS");
        if (providerAddr == address(0)) providerAddr = vm.envAddress("DODO_PMM_PROVIDER");
        address providerSourceAddr = vm.envOr("DODO_PMM_PROVIDER_SOURCE_ADDRESS", address(0));
        if (providerSourceAddr == address(0)) providerSourceAddr = vm.envOr("DODO_PMM_PROVIDER_SOURCE", address(0));
        if (providerSourceAddr == address(0)) providerSourceAddr = providerAddr;
        require(integrationAddr != address(0), "DODO_PMM_INTEGRATION_ADDRESS not set");
        require(providerAddr != address(0), "DODO_PMM_PROVIDER_ADDRESS not set");

        string memory path = vm.envOr("POOL_CONFIG_JSON", string(DEFAULT_CONFIG_PATH));
        string memory json = vm.readFile(path);

        DODOPMMIntegration integration = DODOPMMIntegration(integrationAddr);
        DODOPMMProvider providerSource = DODOPMMProvider(providerSourceAddr);

        uint256 lpFeeRate = vm.envOr("LP_FEE_RATE", json.readUint(".defaults.lpFeeRate"));
        uint256 initialPrice = vm.envOr("INITIAL_PRICE", json.readUint(".defaults.initialPrice"));
        uint256 kFactor = vm.envOr("K_FACTOR", json.readUint(".defaults.kFactor"));
        bool enableTwap = vm.envOr("ENABLE_TWAP", json.readBool(".defaults.enableTwap"));

        string[] memory cStars = json.readStringArray(".groups.cStarSymbols");
        string[] memory officials = json.readStringArray(".groups.officialStableSymbols");
        string memory wethSymbol = json.readString(".groups.wethSymbol");
        bool deployCStarVsCStar = json.readBool(".groups.deploy.cStarVsCStar");
        bool deployCStarVsOfficial = json.readBool(".groups.deploy.cStarVsOfficial");
        bool deployCStarVsWeth = json.readBool(".groups.deploy.cStarVsWeth");
        bool deployOfficialVsWeth = json.readBool(".groups.deploy.officialVsWeth");

        vm.startBroadcast(pk);

        if (deployCStarVsCStar) {
            for (uint256 i = 0; i < cStars.length; i++) {
                for (uint256 j = i + 1; j < cStars.length; j++) {
                    _importIfNeeded(json, providerSource, integration, cStars[i], cStars[j], lpFeeRate, initialPrice, kFactor, enableTwap);
                }
            }
        }

        if (deployCStarVsOfficial) {
            for (uint256 i = 0; i < cStars.length; i++) {
                for (uint256 j = 0; j < officials.length; j++) {
                    _importIfNeeded(json, providerSource, integration, cStars[i], officials[j], lpFeeRate, initialPrice, kFactor, enableTwap);
                }
            }
        }

        if (deployCStarVsWeth) {
            for (uint256 i = 0; i < cStars.length; i++) {
                _importIfNeeded(json, providerSource, integration, cStars[i], wethSymbol, lpFeeRate, initialPrice, kFactor, enableTwap);
            }
        }

        if (deployOfficialVsWeth) {
            for (uint256 i = 0; i < officials.length; i++) {
                _importIfNeeded(json, providerSource, integration, officials[i], wethSymbol, lpFeeRate, initialPrice, kFactor, enableTwap);
            }
        }

        for (uint256 i = 0; json.keyExists(string.concat(".explicitPairs[", vm.toString(i), "]")); i++) {
            string memory baseKey = string.concat(".explicitPairs[", vm.toString(i), "].baseSymbol");
            string memory quoteKey = string.concat(".explicitPairs[", vm.toString(i), "].quoteSymbol");
            string memory explicitBase = json.readString(baseKey);
            string memory explicitQuote = json.readString(quoteKey);
            _importIfNeeded(json, providerSource, integration, explicitBase, explicitQuote, lpFeeRate, initialPrice, kFactor, enableTwap);
        }

        for (uint256 i = 0; json.keyExists(string.concat(".plannedPairs[", vm.toString(i), "]")); i++) {
            string memory baseKey = string.concat(".plannedPairs[", vm.toString(i), "].baseSymbol");
            string memory quoteKey = string.concat(".plannedPairs[", vm.toString(i), "].quoteSymbol");
            string memory plannedBase = json.readString(baseKey);
            string memory plannedQuote = json.readString(quoteKey);
            _importIfNeeded(json, providerSource, integration, plannedBase, plannedQuote, lpFeeRate, initialPrice, kFactor, enableTwap);
        }

        vm.stopBroadcast();
    }

    function _importIfNeeded(
        string memory json,
        DODOPMMProvider provider,
        DODOPMMIntegration integration,
        string memory baseSymbol,
        string memory quoteSymbol,
        uint256 lpFeeRate,
        uint256 initialPrice,
        uint256 kFactor,
        bool enableTwap
    ) internal {
        address base = json.readAddress(string.concat(".tokens.", baseSymbol));
        address quote = json.readAddress(string.concat(".tokens.", quoteSymbol));
        if (base == address(0) || quote == address(0) || base == quote) return;

        address integrationPool = integration.pools(base, quote);
        if (integrationPool != address(0)) return;

        address providerPool = provider.pools(base, quote);
        if (providerPool == address(0)) return;

        integration.importExistingPool(
            providerPool,
            base,
            quote,
            lpFeeRate,
            initialPrice,
            kFactor,
            enableTwap
        );

        console.log("Imported:", baseSymbol, "/", quoteSymbol);
        console.log("Pool:", providerPool);
    }
}
