#!/usr/bin/env node
/**
 * Gelato Network Setup Script
 * Registers PriceFeedKeeper with Gelato Network
 *
 * Usage:
 *   node scripts/reserve/gelato-keeper-setup.js
 *
 * Environment Variables:
 *   RPC_URL_138 - ChainID 138 RPC endpoint
 *   PRIVATE_KEY - Deployer private key
 *   GELATO_OPS - Gelato Ops contract address
 *   PRICE_FEED_KEEPER_ADDRESS - PriceFeedKeeper contract address
 *   EXECUTION_INTERVAL - Execution interval in seconds (default: 30)
 *   FUNDING_AMOUNT - Native token amount to fund (default: 0.1 ETH)
 */

const { ethers } = require('ethers');
require('dotenv').config();

const CONFIG = {
    rpcUrl: process.env.RPC_URL_138 || 'http://localhost:8545',
    privateKey: process.env.PRIVATE_KEY,
    gelatoOps: process.env.GELATO_OPS || '0x527a819db1eb0e34426297b03bae11F2f8B3A19E', // Default Gelato Ops
    keeperAddress: process.env.PRICE_FEED_KEEPER_ADDRESS,
    executionInterval: parseInt(process.env.EXECUTION_INTERVAL || '30'),
    fundingAmount: ethers.parseEther(process.env.FUNDING_AMOUNT || '0.1'),
};

// Gelato Ops ABI (simplified)
const GELATO_OPS_ABI = [
    "function createTask(address execAddress, bytes4 execSelector, address resolverAddress, bytes calldata resolverData) external returns (bytes32)",
    "function getTaskId(address execAddress, bytes4 execSelector, address resolverAddress, bytes calldata resolverData) external view returns (bytes32)",
    "function cancelTask(bytes32 taskId) external",
    "function depositFunds(address taskCreator, address token, uint256 amount) external payable",
    "function getTaskId(address execAddress, bytes4 execSelector, address resolverAddress, bytes calldata resolverData) external view returns (bytes32)",
    "event TaskCreated(bytes32 indexed taskId, address indexed execAddress, bytes4 execSelector, address indexed resolverAddress, bytes resolverData)",
];

// GelatoKeeperCompatible ABI
const GELATO_KEEPER_ABI = [
    "function executeTask() external",
    "function canExec() external view returns (bool canExec, bytes memory execData)",
];

async function main() {
    console.log('=== Gelato Network Setup ===\n');

    // Validate configuration
    if (!CONFIG.privateKey) throw new Error('PRIVATE_KEY is required');
    if (!CONFIG.keeperAddress) throw new Error('PRICE_FEED_KEEPER_ADDRESS is required');

    const provider = new ethers.JsonRpcProvider(CONFIG.rpcUrl);
    const wallet = new ethers.Wallet(CONFIG.privateKey, provider);

    console.log('Network:', CONFIG.rpcUrl);
    console.log('Deployer:', wallet.address);
    console.log('Gelato Ops:', CONFIG.gelatoOps);
    console.log('Keeper Address:', CONFIG.keeperAddress);
    console.log('Execution Interval:', CONFIG.executionInterval, 'seconds');
    console.log('Funding Amount:', ethers.formatEther(CONFIG.fundingAmount), 'ETH');
    console.log('');

    // Check balance
    const balance = await provider.getBalance(wallet.address);
    console.log('Balance:', ethers.formatEther(balance), 'ETH');

    if (balance < CONFIG.fundingAmount) {
        throw new Error(`Insufficient balance. Need ${ethers.formatEther(CONFIG.fundingAmount)} ETH`);
    }

    // Deploy GelatoKeeperCompatible if not already deployed
    console.log('Checking GelatoKeeperCompatible contract...');
    // For now, assume it needs to be deployed via Foundry script
    // In production, deploy it first and set GELATO_KEEPER_COMPATIBLE_ADDRESS

    const gelatoKeeperAddress = process.env.GELATO_KEEPER_COMPATIBLE_ADDRESS;
    if (!gelatoKeeperAddress) {
        console.log('⚠ GELATO_KEEPER_COMPATIBLE_ADDRESS not set');
        console.log('Please deploy GelatoKeeperCompatible contract first using:');
        console.log('forge script script/reserve/DeployGelatoKeeper.s.sol:DeployGelatoKeeper --rpc-url chain138 --broadcast');
        process.exit(1);
    }

    console.log('GelatoKeeperCompatible:', gelatoKeeperAddress);

    // Create task
    console.log('\nCreating Gelato task...');
    const gelatoOps = new ethers.Contract(CONFIG.gelatoOps, GELATO_OPS_ABI, wallet);

    const execAddress = gelatoKeeperAddress;
    const execSelector = '0x3c4b2e02'; // executeTask() selector
    const resolverAddress = gelatoKeeperAddress;
    const resolverData = ethers.AbiCoder.defaultAbiCoder().encode(['bytes4'], ['0x3c4b2e02']); // canExec() selector

    const createTaskTx = await gelatoOps.createTask(
        execAddress,
        execSelector,
        resolverAddress,
        resolverData,
        { value: CONFIG.fundingAmount }
    );

    console.log('Transaction sent:', createTaskTx.hash);
    const receipt = await createTaskTx.wait();

    // Parse TaskCreated event
    const event = receipt.logs.find(log => {
        try {
            const parsed = gelatoOps.interface.parseLog(log);
            return parsed.name === 'TaskCreated';
        } catch {
            return false;
        }
    });

    if (event) {
        const parsed = gelatoOps.interface.parseLog(event);
        const taskId = parsed.args.taskId;
        console.log('✓ Task created!');
        console.log('Task ID:', taskId);
        console.log('');
        console.log('=== Setup Complete ===');
        console.log('Task ID:', taskId);
        console.log('Monitor at: https://app.gelato.network/task/' + taskId);
    } else {
        console.log('⚠ Could not parse TaskCreated event');
        console.log('Check transaction receipt for task ID');
    }
}

main().catch(error => {
    console.error('Error:', error.message);
    process.exit(1);
});

