#!/usr/bin/env bash
# Deploy LINK Token and Verify Confirmation
# This script actually waits for network confirmation
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"

load_explorer_runtime_env

RPC_URL="${RPC_URL_138:-http://192.168.11.250:8545}"
GAS_PRICE="${1:-$(cast --to-wei 20 gwei)}"
ACCOUNT=$(cast wallet address "$PRIVATE_KEY")

echo "╔══════════════════════════════════════════════════════════════╗"
echo "║     DEPLOY AND VERIFY LINK TOKEN                              ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo ""
echo "Account: $ACCOUNT"
echo "RPC: $RPC_URL"
echo "Gas: $(echo "scale=2; $GAS_PRICE / 1000000000" | bc) gwei"
echo ""

TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT

cd "$TEMP_DIR"
forge init --no-git --force . > /dev/null 2>&1

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

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));
        link.mint(vm.addr(deployerPrivateKey), 1_000_000e18);
        vm.stopBroadcast();
    }
}
EOF

export PRIVATE_KEY

echo "=== Compiling ==="
forge build > /dev/null 2>&1
echo "✓ Compiled"
echo ""

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

# Extract address from console output
LINK_ADDRESS=$(echo "$DEPLOY_OUTPUT" | grep -oE "LINK_TOKEN_ADDRESS[[:space:]]+0x[0-9a-fA-F]{40}" | awk '{print $2}' || echo "")

if [ -z "$LINK_ADDRESS" ] || [ ${#LINK_ADDRESS} -ne 42 ]; then
    echo "❌ Failed to extract deployment address"
    echo "Output:"
    echo "$DEPLOY_OUTPUT" | tail -20
    exit 1
fi

echo "✓ Transaction sent: $LINK_ADDRESS"
echo ""

echo "=== Waiting for Network Confirmation ==="
echo "This may take 1-5 minutes..."
echo ""

MAX_WAIT=300  # 5 minutes
ELAPSED=0
CONFIRMED=false

while [ $ELAPSED -lt $MAX_WAIT ]; do
    CODE=$(cast code "$LINK_ADDRESS" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    
    if [ -n "$CODE" ] && [ "$CODE" != "0x" ] && [ ${#CODE} -gt 100 ]; then
        echo "✅✅✅ CONFIRMED!"
        echo "Address: $LINK_ADDRESS"
        echo "Bytecode: ${#CODE} chars"
        CONFIRMED=true
        break
    fi
    
    if [ $((ELAPSED % 30)) -eq 0 ]; then
        echo "  Waiting... (${ELAPSED}s / ${MAX_WAIT}s)"
    fi
    
    sleep 10
    ELAPSED=$((ELAPSED + 10))
done

if [ "$CONFIRMED" != "true" ]; then
    echo ""
    echo "⏳ Deployment not confirmed after ${MAX_WAIT} seconds"
    echo "Address: $LINK_ADDRESS"
    echo "Check manually: cast code $LINK_ADDRESS --rpc-url $RPC_URL"
    echo ""
    echo "Possible reasons:"
    echo "1. Network is slow to confirm"
    echo "2. Transaction may have failed"
    echo "3. RPC node may be out of sync"
    echo ""
    echo "Check block explorer: https://explorer.d-bis.org/address/$ACCOUNT"
    exit 1
fi

echo ""
echo "=== Updating address inventory ==="
persist_inventory_value "LINK_TOKEN" "$LINK_ADDRESS"
persist_inventory_value "CCIP_CHAIN138_FEE_TOKEN" "$LINK_ADDRESS"
echo "✓ Updated config/address-inventory.json"
echo ""

echo "=== Verifying Token Functions ==="
NAME=$(cast call "$LINK_ADDRESS" "name()" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-ascii 2>/dev/null | tr -d '\0' || echo "")
SYMBOL=$(cast call "$LINK_ADDRESS" "symbol()" --rpc-url "$RPC_URL" 2>/dev/null | cast --to-ascii 2>/dev/null | tr -d '\0' || echo "")
BALANCE=$(cast call "$LINK_ADDRESS" "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 "Name: $NAME"
echo "Symbol: $SYMBOL"
echo "Account Balance: $BALANCE_ETH LINK"
echo ""

if (( $(echo "$BALANCE_ETH < 20" | bc -l 2>/dev/null || echo 1) )); then
    echo "=== Minting Additional Tokens ==="
    MINT_AMOUNT="1000000000000000000000000"
    cast send "$LINK_ADDRESS" "mint(address,uint256)" "$ACCOUNT" "$MINT_AMOUNT" \
        --rpc-url "$RPC_URL" \
        --private-key "$PRIVATE_KEY" \
        --gas-price "$GAS_PRICE" \
        --legacy \
        2>&1 | tail -3
    
    echo "Waiting 20 seconds for mint confirmation..."
    sleep 20
    
    BALANCE=$(cast call "$LINK_ADDRESS" "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 "New Balance: $BALANCE_ETH LINK"
    echo ""
fi

echo "✅✅✅ LINK TOKEN DEPLOYMENT COMPLETE!"
echo "Address: $LINK_ADDRESS"
echo ""
