#!/usr/bin/env bash
# CCIP Send Script
# Sends tokens via CCIP bridge to a destination chain
#
# Usage:
#   ./ccip-send.sh --selector <chain-selector> --receiver <address> --amount <wei> [--dry-run]
#
# Example:
#   export BRIDGE_ADDRESS=$CCIPWETH9_BRIDGE_CHAIN138
#   ./ccip-send.sh --selector 5009297550715157269 --receiver 0xYourMainnetAddress --amount 100000000000000000

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"

# Load environment variables
ENV_FILE="${ENV_FILE:-$PROJECT_ROOT/.env}"
if [ -f "$ENV_FILE" ]; then
    export $(grep -v '^#' "$ENV_FILE" | grep -E "^(RPC_URL|PRIVATE_KEY|CHAIN_ID|CCIP_ROUTER|LINK_TOKEN|WETH9_ADDRESS|WETH10_ADDRESS|FEE_TOKEN)" | xargs)
fi

# Default values
DRY_RUN=false
SELECTOR=""
RECEIVER=""
AMOUNT=""

# Parse arguments
while [[ $# -gt 0 ]]; do
    case "$1" in
        --selector)
            SELECTOR="$2"
            shift 2
            ;;
        --receiver)
            RECEIVER="$2"
            shift 2
            ;;
        --amount)
            AMOUNT="$2"
            shift 2
            ;;
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        *)
            echo "Unknown argument: $1"
            echo ""
            echo "Usage: $0 --selector <chain-selector> --receiver <address> --amount <wei> [--dry-run]"
            echo ""
            echo "Arguments:"
            echo "  --selector <chain-selector>  CCIP chain selector (required)"
            echo "  --receiver <address>         Receiver address on destination chain (required)"
            echo "  --amount <wei>               Amount to bridge in wei (required)"
            echo "  --dry-run                    Simulate transaction without sending (optional)"
            echo ""
            echo "Environment variables:"
            echo "  BRIDGE_ADDRESS               Bridge contract address (required)"
            echo "  RPC_URL                      RPC endpoint URL (required)"
            echo "  PRIVATE_KEY                  Private key for signing (required)"
            echo "  FEE_TOKEN                    Fee token address (0x0 for native, or LINK)"
            echo ""
            echo "Examples:"
            echo "  # Dry run: estimate without sending"
            echo "  export BRIDGE_ADDRESS=\$CCIPWETH9_BRIDGE_CHAIN138"
            echo "  $0 --selector 5009297550715157269 --receiver 0xYourAddress --amount 100000000000000000 --dry-run"
            echo ""
            echo "  # Actual send"
            echo "  $0 --selector 5009297550715157269 --receiver 0xYourAddress --amount 100000000000000000"
            exit 1
            ;;
    esac
done

# Validate required arguments
if [ -z "$SELECTOR" ] || [ -z "$RECEIVER" ] || [ -z "$AMOUNT" ]; then
    echo "Error: Missing required arguments"
    echo "Usage: $0 --selector <chain-selector> --receiver <address> --amount <wei> [--dry-run]"
    exit 1
fi

# Validate required environment variables
if [ -z "${BRIDGE_ADDRESS:-}" ]; then
    echo "Error: BRIDGE_ADDRESS not set"
    echo "Set it to the bridge contract address:"
    echo "  export BRIDGE_ADDRESS=\$CCIPWETH9_BRIDGE_CHAIN138"
    exit 1
fi

if [ -z "${RPC_URL:-}" ]; then
    echo "Error: RPC_URL not set"
    exit 1
fi

if [ "$DRY_RUN" = false ] && [ -z "${PRIVATE_KEY:-}" ]; then
    echo "Error: PRIVATE_KEY not set (required for actual send)"
    exit 1
fi

# Default to LINK token if FEE_TOKEN not set
FEE_TOKEN="${FEE_TOKEN:-${LINK_TOKEN:-0x0000000000000000000000000000000000000000}}"

# Validate cast is available
if ! cast --version &>/dev/null; then
    echo "Error: cast (Foundry) not found. Please install Foundry:"
    echo "  curl -L https://foundry.paradigm.xyz | bash"
    exit 1
fi

BRIDGE_ADDRESS=$(cast --to-checksum-address "$BRIDGE_ADDRESS")
RECEIVER=$(cast --to-checksum-address "$RECEIVER")

echo "=========================================="
if [ "$DRY_RUN" = true ]; then
    echo "CCIP Send (DRY RUN)"
else
    echo "CCIP Send"
fi
echo "=========================================="
echo "Bridge Address: $BRIDGE_ADDRESS"
echo "Chain Selector: $SELECTOR"
echo "Receiver: $RECEIVER"
echo "Amount: $AMOUNT wei"
echo "Fee Token: $FEE_TOKEN"
echo ""

# Estimate fee first
echo "Estimating fee..."
FEE=$(cast call "$BRIDGE_ADDRESS" \
    "estimateCcipFee(uint64,address,uint256)(uint256)" \
    "$SELECTOR" \
    "$RECEIVER" \
    "$AMOUNT" \
    --rpc-url "$RPC_URL" 2>/dev/null || echo "0")

if [ "$FEE" = "0" ] || [ -z "$FEE" ]; then
    echo "⚠ Warning: Could not estimate fee. Proceeding anyway..."
    FEE="0"
else
    FEE_DECIMAL=$(cast --to-dec "$FEE" 2>/dev/null || echo "$FEE")
    echo "Estimated fee: $FEE wei ($FEE_DECIMAL)"
fi

# Check sender balance and approval
if [ "$DRY_RUN" = false ]; then
    SENDER_ADDRESS=$(cast wallet address --private-key "$PRIVATE_KEY" 2>/dev/null || echo "")
    if [ -z "$SENDER_ADDRESS" ]; then
        echo "Error: Could not derive address from private key"
        exit 1
    fi
    
    echo ""
    echo "Checking sender balance and approvals..."
    echo "Sender: $SENDER_ADDRESS"
    
    # Determine which token (WETH9 or WETH10) based on bridge address
    # This is a heuristic - you may need to adjust based on your setup
    if [[ "$BRIDGE_ADDRESS" == *"WETH9"* ]] || [[ "${BRIDGE_ADDRESS:-}" == "${CCIPWETH9_BRIDGE_CHAIN138:-}" ]] || [[ "${BRIDGE_ADDRESS:-}" == "${CCIPWETH9_BRIDGE_MAINNET:-}" ]]; then
        TOKEN_ADDRESS="${WETH9_ADDRESS:-0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2}"
        TOKEN_NAME="WETH9"
    else
        TOKEN_ADDRESS="${WETH10_ADDRESS:-0xf4BB2e28688e89fCcE3c0580D37d36A7672E8A9f}"
        TOKEN_NAME="WETH10"
    fi
    
    # Check token balance
    BALANCE=$(cast call "$TOKEN_ADDRESS" \
        "balanceOf(address)(uint256)" \
        "$SENDER_ADDRESS" \
        --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
    
    if [ "$(cast --to-dec "$BALANCE" 2>/dev/null || echo "0")" -lt "$(cast --to-dec "$AMOUNT" 2>/dev/null || echo "0")" ]; then
        echo "⚠ Warning: Insufficient $TOKEN_NAME balance"
        echo "  Required: $AMOUNT wei"
        echo "  Available: $BALANCE wei"
    else
        echo "✓ Sufficient $TOKEN_NAME balance"
    fi
    
    # Check approval
    ALLOWANCE=$(cast call "$TOKEN_ADDRESS" \
        "allowance(address,address)(uint256)" \
        "$SENDER_ADDRESS" \
        "$BRIDGE_ADDRESS" \
        --rpc-url "$RPC_URL" 2>/dev/null || echo "0")
    
    if [ "$(cast --to-dec "$ALLOWANCE" 2>/dev/null || echo "0")" -lt "$(cast --to-dec "$AMOUNT" 2>/dev/null || echo "0")" ]; then
        echo "⚠ Warning: Insufficient approval"
        echo "  Required: $AMOUNT wei"
        echo "  Approved: $ALLOWANCE wei"
        echo ""
        echo "Approve the bridge to spend tokens:"
        echo "  cast send $TOKEN_ADDRESS \\"
        echo "    \"approve(address,uint256)(bool)\" \\"
        echo "    $BRIDGE_ADDRESS $AMOUNT \\"
        echo "    --private-key \$PRIVATE_KEY \\"
        echo "    --rpc-url \$RPC_URL"
        if [ "$DRY_RUN" = false ]; then
            read -p "Continue anyway? [y/N]: " confirm
            if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
                echo "Aborted. Please approve first."
                exit 1
            fi
        fi
    else
        echo "✓ Sufficient approval"
    fi
fi

echo ""

if [ "$DRY_RUN" = true ]; then
    echo "DRY RUN: Simulating bridgeOut call..."
    cast call "$BRIDGE_ADDRESS" \
        "bridgeOut(uint64,address,uint256,address)(bytes32)" \
        "$SELECTOR" \
        "$RECEIVER" \
        "$AMOUNT" \
        "$FEE_TOKEN" \
        --rpc-url "$RPC_URL" || {
        echo "Error: Dry run failed"
        exit 1
    }
    echo "✓ Dry run successful (transaction would succeed)"
else
    echo "Sending transaction..."
    
    # Determine value to send (if using native fees)
    VALUE="0"
    if [ "$FEE_TOKEN" = "0x0000000000000000000000000000000000000000" ]; then
        VALUE="$FEE"
    fi
    
    TX_HASH=$(cast send "$BRIDGE_ADDRESS" \
        "bridgeOut(uint64,address,uint256,address)(bytes32)" \
        "$SELECTOR" \
        "$RECEIVER" \
        "$AMOUNT" \
        "$FEE_TOKEN" \
        --private-key "$PRIVATE_KEY" \
        --rpc-url "$RPC_URL" \
        --value "$VALUE" \
        --gas-limit 500000 2>&1 | grep -oP '0x[a-fA-F0-9]{64}' || echo "")
    
    if [ -z "$TX_HASH" ]; then
        echo "Error: Transaction failed or hash not found"
        exit 1
    fi
    
    echo "✓ Transaction sent!"
    echo "  Transaction Hash: $TX_HASH"
    echo ""
    echo "Waiting for confirmation..."
    sleep 5
    
    # Try to get receipt
    RECEIPT=$(cast receipt "$TX_HASH" --rpc-url "$RPC_URL" 2>/dev/null || echo "")
    if [ -n "$RECEIPT" ]; then
        echo "✓ Transaction confirmed"
    else
        echo "⚠ Transaction may still be pending. Check with:"
        echo "  cast receipt $TX_HASH --rpc-url $RPC_URL"
    fi
fi

echo ""
echo "=========================================="
echo "Complete"
echo "=========================================="

