#!/bin/bash
# Diagnose and fix LINK token deployment issues

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
source "$PROJECT_ROOT/scripts/lib/address-inventory.sh"
cd "$PROJECT_ROOT"

load_explorer_runtime_env

RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}"
ACCOUNT=$(cast wallet address "$PRIVATE_KEY" 2>/dev/null || echo "")
FOUND_LINK=""

if [ -z "$ACCOUNT" ]; then
    echo "Error: PRIVATE_KEY not set or invalid"
    exit 1
fi

echo "╔══════════════════════════════════════════════════════════════╗"
echo "║     LINK TOKEN DEPLOYMENT DIAGNOSTIC                         ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "Account: $ACCOUNT"
echo "RPC: $RPC_URL"
echo ""

# Check network
echo "=== Network Status ==="
BLOCK=$(cast block-number --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
CHAIN_ID=$(cast chain-id --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
echo "Block: $BLOCK"
echo "Chain ID: $CHAIN_ID"
echo ""

# Check account nonce and recent transactions
echo "=== Account Status ==="
NONCE=$(cast nonce "$ACCOUNT" --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
BALANCE=$(cast balance "$ACCOUNT" --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
BALANCE_ETH=$(cast --from-wei "$BALANCE" ether 2>/dev/null || echo "0")
echo "Nonce: $NONCE"
echo "Balance: $BALANCE_ETH ETH"
echo ""

# Check CCIP Router for fee token
echo "=== Checking CCIP Router for Fee Token ==="
CCIP_ROUTER="$(resolve_address_value CCIP_ROUTER_ADDRESS CCIP_ROUTER_ADDRESS 0x42DAb7b888Dd382bD5Adcf9E038dBF1fD03b4817)"
ROUTER_CODE=$(cast code "$CCIP_ROUTER" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
if [ -n "$ROUTER_CODE" ] && [ "$ROUTER_CODE" != "0x" ]; then
    echo "✓ CCIP Router exists"
    FEE_TOKEN_RAW=$(cast call "$CCIP_ROUTER" "feeToken()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    if [ -n "$FEE_TOKEN_RAW" ] && [ "$FEE_TOKEN_RAW" != "0x" ]; then
        LINK_FROM_ROUTER=$(echo "$FEE_TOKEN_RAW" | sed 's/0x000000000000000000000000//' | sed 's/^0x//' | sed 's/^/0x/')
        echo "Router fee token: $LINK_FROM_ROUTER"
        CODE=$(cast code "$LINK_FROM_ROUTER" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
        if [ -n "$CODE" ] && [ "$CODE" != "0x" ] && [ ${#CODE} -gt 100 ]; then
            echo "✓✓✓ LINK token EXISTS at router address!"
            FOUND_LINK="$LINK_FROM_ROUTER"
        else
            echo "✗ Router references LINK, but contract not deployed"
        fi
    fi
fi
echo ""

# Check if LINK token exists at any known address
echo "=== Checking Known LINK Addresses ==="
KNOWN_LINKS=(
    "$(resolve_address_value LINK_TOKEN LINK_TOKEN 0x514910771AF9Ca656af840dff83E8264EcF986CA)"
    "0x0cb0192C056aa425C557BdeAD8E56C7eEabf7acF"
    "0x07dE1f489E1bfCE2c326066a9DFc10e731CBA0CB"
    "0x514910771AF9Ca656af840dff83E8264EcF986CA"
)

if [ -z "$FOUND_LINK" ]; then
    for LINK_ADDR in "${KNOWN_LINKS[@]}"; do
    CODE=$(cast code "$LINK_ADDR" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    if [ -n "$CODE" ] && [ "$CODE" != "0x" ] && [ ${#CODE} -gt 100 ]; then
        echo "✓ Found LINK at: $LINK_ADDR"
        NAME=$(cast call "$LINK_ADDR" "name()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
        SYMBOL=$(cast call "$LINK_ADDR" "symbol()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
        echo "  Name: $NAME"
        echo "  Symbol: $SYMBOL"
        FOUND_LINK="$LINK_ADDR"
        break
    else
        echo "✗ No contract at: $LINK_ADDR"
    fi
    done
fi
echo ""

# If found, use it
if [ -n "$FOUND_LINK" ]; then
    echo "=== Using Existing LINK Token ==="
    echo "LINK Token: $FOUND_LINK"
    persist_inventory_value "LINK_TOKEN" "$FOUND_LINK" || true
    persist_inventory_value "CCIP_CHAIN138_FEE_TOKEN" "$FOUND_LINK" || true
    echo "✓ Updated address inventory"
    
    # Check balance
    BALANCE=$(cast call "$FOUND_LINK" "balanceOf(address)" "$ACCOUNT" --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
    BALANCE_ETH=$(cast --from-wei "$BALANCE" ether 2>/dev/null || echo "0")
    echo "Account Balance: $BALANCE_ETH LINK"
    
    # Try to mint if balance is low
    if (( $(echo "$BALANCE_ETH < 20" | bc -l 2>/dev/null || echo 1) )); then
        echo ""
        echo "=== Attempting to Mint ==="
        FORCE_GAS="3000000000"
        CURRENT_NONCE=$(cast nonce "$ACCOUNT" --rpc-url "$RPC_URL")
        echo "Minting 1M LINK with nonce $CURRENT_NONCE..."
        MINT_OUTPUT=$(cast send "$FOUND_LINK" "mint(address,uint256)" "$ACCOUNT" $(cast --to-wei 1000000 ether) \
            --rpc-url "$RPC_URL" \
            --private-key "$PRIVATE_KEY" \
            --gas-price "$FORCE_GAS" \
            --nonce "$CURRENT_NONCE" \
            --legacy 2>&1 || echo "FAILED")
        
        if echo "$MINT_OUTPUT" | grep -qE "(blockHash|transactionHash)"; then
            echo "✓ Mint transaction sent"
            TX_HASH=$(echo "$MINT_OUTPUT" | grep -oE "0x[0-9a-f]{64}" | head -1)
            echo "Transaction: $TX_HASH"
            echo "Waiting 15 seconds for confirmation..."
            sleep 15
        else
            echo "⚠ Mint may not be available (standard LINK token)"
            echo "You may need to acquire LINK from another source"
        fi
    fi
    
    exit 0
fi

# If not found, try fresh deployment
echo "=== No Existing LINK Found - Deploying Fresh ==="
echo ""

TEMP_DIR=$(mktemp -d)
cd "$TEMP_DIR"

# Create minimal project
forge init --no-git --force . > /dev/null 2>&1

# Create MockLinkToken
cat > src/MockLinkToken.sol << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract MockLinkToken {
    string public name = "Chainlink Token";
    string public symbol = "LINK";
    uint8 public decimals = 18;
    
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    uint256 public totalSupply;
    
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    
    function mint(address to, uint256 amount) external {
        balanceOf[to] += amount;
        totalSupply += amount;
        emit Transfer(address(0), to, amount);
    }
    
    function transfer(address to, uint256 amount) external returns (bool) {
        require(balanceOf[msg.sender] >= amount, "insufficient balance");
        balanceOf[msg.sender] -= amount;
        balanceOf[to] += amount;
        emit Transfer(msg.sender, to, amount);
        return true;
    }
    
    function transferFrom(address from, address to, uint256 amount) external returns (bool) {
        require(balanceOf[from] >= amount, "insufficient balance");
        require(allowance[from][msg.sender] >= amount, "insufficient allowance");
        balanceOf[from] -= amount;
        balanceOf[to] += amount;
        allowance[from][msg.sender] -= amount;
        emit Transfer(from, to, amount);
        return true;
    }
    
    function approve(address spender, uint256 amount) external returns (bool) {
        allowance[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }
}
EOF

# Create deployment script
cat > script/DeployLink.s.sol << 'EOF'
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {Script, console} from "forge-std/Script.sol";
import {MockLinkToken} from "../src/MockLinkToken.sol";

contract DeployLink is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);
        
        MockLinkToken link = new MockLinkToken();
        console.log("LINK_TOKEN_ADDRESS", address(link));
        
        // Mint 1M LINK to deployer
        link.mint(vm.addr(deployerPrivateKey), 1_000_000e18);
        console.log("Minted 1M LINK");
        
        vm.stopBroadcast();
    }
}
EOF

# Build
echo "Building contract..."
forge build > /dev/null 2>&1

# Deploy with very high gas
FORCE_GAS="5000000000"  # 5 gwei
CURRENT_NONCE=$(cast nonce "$ACCOUNT" --rpc-url "$RPC_URL")

echo "Deploying with:"
echo "  Gas: $FORCE_GAS wei ($(echo "scale=2; $FORCE_GAS / 1000000000" | bc) gwei)"
echo "  Nonce: $CURRENT_NONCE"
echo ""

DEPLOY_OUTPUT=$(forge script script/DeployLink.s.sol:DeployLink \
    --rpc-url "$RPC_URL" \
    --private-key "$PRIVATE_KEY" \
    --broadcast \
    --skip-simulation \
    --gas-price "$FORCE_GAS" \
    --legacy \
    -vv 2>&1 || echo "FAILED")

NEW_LINK=$(echo "$DEPLOY_OUTPUT" | grep -oE "LINK_TOKEN_ADDRESS[[:space:]]+0x[0-9a-fA-F]{40}" | awk '{print $2}')

if [ -z "$NEW_LINK" ]; then
    NEW_LINK=$(echo "$DEPLOY_OUTPUT" | grep -oE "0x[0-9a-fA-F]{40}" | head -1)
fi

if [ -n "$NEW_LINK" ] && [ ${#NEW_LINK} -eq 42 ]; then
    echo "✓✓✓ LINK deployed: $NEW_LINK"
    echo "$NEW_LINK" > /tmp/link_address.txt
    
    # Update address inventory
    cd "$PROJECT_ROOT"
    persist_inventory_value "LINK_TOKEN" "$NEW_LINK" || true
    persist_inventory_value "CCIP_CHAIN138_FEE_TOKEN" "$NEW_LINK" || true
    echo "✓ Updated address inventory"
    
    # Wait and verify
    echo ""
    echo "Waiting 30 seconds for network confirmation..."
    sleep 30
    
    CODE=$(cast code "$NEW_LINK" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    if [ -n "$CODE" ] && [ "$CODE" != "0x" ] && [ ${#CODE} -gt 100 ]; then
        echo "✓✓✓ Contract CONFIRMED!"
        NAME=$(cast call "$NEW_LINK" "name()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
        SYMBOL=$(cast call "$NEW_LINK" "symbol()" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
        echo "  Name: $NAME"
        echo "  Symbol: $SYMBOL"
        
        BALANCE=$(cast call "$NEW_LINK" "balanceOf(address)" "$ACCOUNT" --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
        BALANCE_ETH=$(cast --from-wei "$BALANCE" ether 2>/dev/null || echo "0")
        echo "  Balance: $BALANCE_ETH LINK"
        
        if (( $(echo "$BALANCE_ETH < 20" | bc -l 2>/dev/null || echo 1) )); then
            echo ""
            echo "⚠ Balance low, waiting for mint to confirm..."
            for i in {1..12}; do
                sleep 5
                BALANCE=$(cast call "$NEW_LINK" "balanceOf(address)" "$ACCOUNT" --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
                BALANCE_ETH=$(cast --from-wei "$BALANCE" ether 2>/dev/null || echo "0")
                if (( $(echo "$BALANCE_ETH >= 20" | bc -l 2>/dev/null || echo 0) )); then
                    echo "✓ Balance confirmed: $BALANCE_ETH LINK"
                    break
                fi
            done
        fi
    else
        echo "⚠ Contract not yet confirmed"
        echo "Code length: ${#CODE}"
        echo "This may take additional time. Check again with:"
        echo "  cast code $NEW_LINK --rpc-url $RPC_URL"
    fi
else
    echo "✗ Deployment failed"
    echo "Output:"
    echo "$DEPLOY_OUTPUT" | grep -E "(Error|error|FAILED|revert)" | head -10
fi

# Cleanup
rm -rf "$TEMP_DIR"
