#!/usr/bin/env bash

# Deploy Contracts in Proper Order
# This script deploys all contracts in the correct order and updates .env with deployed addresses

set -e


# Script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/../lib/init.sh"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
cd "$PROJECT_ROOT"
# Load .env via dotenv (RPC CR/LF trim). Fallback: raw source.
if [[ -f "$SCRIPT_DIR/../lib/deployment/dotenv.sh" ]]; then
  # shellcheck disable=SC1090
  source "$SCRIPT_DIR/../lib/deployment/dotenv.sh"
  load_deployment_env --repo-root "${PROJECT_ROOT:-$REPO_ROOT}"
elif [[ -n "${PROJECT_ROOT:-}" && -f "$PROJECT_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$PROJECT_ROOT/.env"
  set +a
elif [[ -n "${REPO_ROOT:-}" && -f "$REPO_ROOT/.env" ]]; then
  set -a
  # shellcheck disable=SC1090
  source "$REPO_ROOT/.env"
  set +a
fi

# Load environment variables
if [ ! -f .env ]; then
    log_error "Error: .env file not found"
    echo "Please create .env file with required variables"
    exit 1
fi

source .env

# Check required variables
if [ -z "$PRIVATE_KEY" ]; then
    log_error "Error: PRIVATE_KEY not set in .env"
    exit 1
fi

if [ -z "$RPC_URL" ]; then
    log_error "Error: RPC_URL not set in .env"
    exit 1
fi

# Verify RPC endpoint is accessible
log_warn "Verifying RPC endpoint..."
if ! curl -s -X POST "$RPC_URL" -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' > /dev/null 2>&1; then
    log_error "Error: RPC endpoint is not accessible"
    echo "Please ensure the blockchain is deployed and RPC endpoint is accessible"
    exit 1
fi

log_success "✅ RPC endpoint is accessible"

# Function to update .env file
update_env() {
    local key=$1
    local value=$2
    if grep -q "^${key}=" .env; then
        sed -i "s|^${key}=.*|${key}=${value}|" .env
    else
        echo "${key}=${value}" >> .env
    fi
    log_success "✅ Updated .env: ${key}=${value}"
}

# Function to deploy contract and extract address
deploy_contract() {
    local script_name=$1
    local contract_name=$2
    local env_var=$3
    local additional_args=$4
    
    log_warn "Deploying ${contract_name}..."
    
    # Run deployment script
    local output=$(forge_scoped script "$script_name" \
        --rpc-url "$RPC_URL" \
        --broadcast \
        --private-key "$PRIVATE_KEY" \
        -vvv \
        $additional_args 2>&1)
    
    # Extract deployed address from output
    local address=$(echo "$output" | grep -oE "Deployed.*at: 0x[a-fA-F0-9]{40}" | tail -1 | grep -oE "0x[a-fA-F0-9]{40}" || echo "")
    
    if [ -z "$address" ]; then
        # Try alternative pattern
        address=$(echo "$output" | grep -oE "0x[a-fA-F0-9]{40}" | tail -1 || echo "")
    fi
    
    if [ -z "$address" ]; then
        log_error "Error: Failed to extract address for ${contract_name}"
        echo "Output: $output"
        return 1
    fi
    
    log_success "✅ ${contract_name} deployed at: ${address}"
    update_env "$env_var" "$address"
    echo "$address"
}

# Deployment Order:
# 1. CCIP Router (if deploying custom)
# 2. LINK Token (if deploying, or use existing)
# 3. WETH9
# 4. WETH10
# 5. CCIPWETH9Bridge
# 6. CCIPWETH10Bridge
# 7. Oracle Aggregator
# 8. CCIPSender/Receiver

log_success "=== Starting Contract Deployment ==="

# Step 1: Deploy CCIP Router (if not already deployed)
if [ -z "$CCIP_ROUTER" ] || [ "$CCIP_ROUTER" = "0x0000000000000000000000000000000000000000" ]; then
    log_warn "Step 1: Deploying CCIP Router..."
    
    # CCIP Router requires: feeToken, baseFee, dataFeePerByte
    # For now, we'll deploy with default values (can be configured later)
    FEE_TOKEN=${CCIP_FEE_TOKEN:-"0x0000000000000000000000000000000000000000"}
    BASE_FEE=${CCIP_BASE_FEE:-"1000000000000000"} # 0.001 ETH
    DATA_FEE_PER_BYTE=${CCIP_DATA_FEE_PER_BYTE:-"1000000000"} # 1 gwei per byte
    
    if [ "$FEE_TOKEN" = "0x0000000000000000000000000000000000000000" ]; then
        log_warn "Warning: CCIP_FEE_TOKEN not set. Using zero address (native token)"
    fi
    
    CCIP_ROUTER_ADDRESS=$(forge_scoped script script/DeployCCIPRouter.s.sol:DeployCCIPRouter \
        --sig "run(address,uint256,uint256)" "$FEE_TOKEN" "$BASE_FEE" "$DATA_FEE_PER_BYTE" \
        --rpc-url "$RPC_URL" \
        --broadcast \
        --private-key "$PRIVATE_KEY" \
        -vvv 2>&1 | grep -oE "0x[a-fA-F0-9]{40}" | tail -1)
    
    if [ -n "$CCIP_ROUTER_ADDRESS" ]; then
        update_env "CCIP_ROUTER" "$CCIP_ROUTER_ADDRESS"
        CCIP_ROUTER="$CCIP_ROUTER_ADDRESS"
        log_success "✅ CCIP Router deployed at: ${CCIP_ROUTER}"
    else
        log_error "Error: Failed to deploy CCIP Router"
        exit 1
    fi
else
    log_success "✅ CCIP Router already configured: ${CCIP_ROUTER}"
fi

# Step 2: Deploy or identify LINK Token
if [ -z "$CCIP_FEE_TOKEN" ] || [ "$CCIP_FEE_TOKEN" = "0x0000000000000000000000000000000000000000" ]; then
    log_warn "Step 2: LINK Token not configured"
    log_warn "Note: If using native token for fees, set CCIP_FEE_TOKEN to zero address"
    log_warn "Otherwise, deploy LINK token or set CCIP_FEE_TOKEN to existing address"
    # For now, we'll use native token (zero address)
    update_env "CCIP_FEE_TOKEN" "0x0000000000000000000000000000000000000000"
    CCIP_FEE_TOKEN="0x0000000000000000000000000000000000000000"
else
    log_success "✅ CCIP Fee Token configured: ${CCIP_FEE_TOKEN}"
fi

# Step 3: Deploy WETH9
if [ -z "$WETH9_ADDRESS" ] || [ "$WETH9_ADDRESS" = "0x0000000000000000000000000000000000000000" ] || [ "${DEPLOY_WETH9:-true}" = "true" ]; then
    log_warn "Step 3: Deploying WETH9..."
    WETH9_ADDRESS=$(deploy_contract "script/DeployWETH.s.sol:DeployWETH" "WETH9" "WETH9_ADDRESS")
    if [ -z "$WETH9_ADDRESS" ]; then
        log_error "Error: Failed to deploy WETH9"
        exit 1
    fi
else
    log_success "✅ WETH9 already configured: ${WETH9_ADDRESS}"
fi

# Step 4: Deploy WETH10
if [ -z "$WETH10_ADDRESS" ] || [ "$WETH10_ADDRESS" = "0x0000000000000000000000000000000000000000" ] || [ "${DEPLOY_WETH10:-true}" = "true" ]; then
    log_warn "Step 4: Deploying WETH10..."
    WETH10_ADDRESS=$(deploy_contract "script/DeployWETH10.s.sol:DeployWETH10" "WETH10" "WETH10_ADDRESS")
    if [ -z "$WETH10_ADDRESS" ]; then
        log_error "Error: Failed to deploy WETH10"
        exit 1
    fi
else
    log_success "✅ WETH10 already configured: ${WETH10_ADDRESS}"
fi

# Step 5: Deploy CCIPWETH9Bridge
if [ "${DEPLOY_BRIDGES:-true}" = "true" ]; then
    log_warn "Step 5: Deploying CCIPWETH9Bridge..."
    if [ -z "$CCIP_ROUTER" ] || [ -z "$WETH9_ADDRESS" ] || [ -z "$CCIP_FEE_TOKEN" ]; then
        log_error "Error: Missing required configuration for CCIPWETH9Bridge"
        echo "Required: CCIP_ROUTER, WETH9_ADDRESS, CCIP_FEE_TOKEN"
        exit 1
    fi
    
    # Update .env temporarily for deployment script
    export CCIP_ROUTER
    export WETH9_ADDRESS
    export CCIP_FEE_TOKEN
    
    CCIPWETH9BRIDGE_ADDRESS=$(deploy_contract "script/DeployCCIPWETH9Bridge.s.sol:DeployCCIPWETH9Bridge" "CCIPWETH9Bridge" "CCIPWETH9BRIDGE_ADDRESS")
    if [ -z "$CCIPWETH9BRIDGE_ADDRESS" ]; then
        log_error "Error: Failed to deploy CCIPWETH9Bridge"
        exit 1
    fi
else
    log_success "✅ CCIPWETH9Bridge deployment skipped"
fi

# Step 6: Deploy CCIPWETH10Bridge
if [ "${DEPLOY_BRIDGES:-true}" = "true" ]; then
    log_warn "Step 6: Deploying CCIPWETH10Bridge..."
    if [ -z "$CCIP_ROUTER" ] || [ -z "$WETH10_ADDRESS" ] || [ -z "$CCIP_FEE_TOKEN" ]; then
        log_error "Error: Missing required configuration for CCIPWETH10Bridge"
        echo "Required: CCIP_ROUTER, WETH10_ADDRESS, CCIP_FEE_TOKEN"
        exit 1
    fi
    
    # Update .env temporarily for deployment script
    export CCIP_ROUTER
    export WETH10_ADDRESS
    export CCIP_FEE_TOKEN
    
    CCIPWETH10BRIDGE_ADDRESS=$(deploy_contract "script/DeployCCIPWETH10Bridge.s.sol:DeployCCIPWETH10Bridge" "CCIPWETH10Bridge" "CCIPWETH10BRIDGE_ADDRESS")
    if [ -z "$CCIPWETH10BRIDGE_ADDRESS" ]; then
        log_error "Error: Failed to deploy CCIPWETH10Bridge"
        exit 1
    fi
else
    log_success "✅ CCIPWETH10Bridge deployment skipped"
fi

# Step 7: Deploy Oracle Aggregator
log_warn "Step 7: Deploying Oracle Aggregator..."
ORACLE_DESCRIPTION=${ORACLE_DESCRIPTION:-"ETH/USD Price Feed"}
ORACLE_HEARTBEAT=${ORACLE_HEARTBEAT:-"60"}
ORACLE_DEVIATION_THRESHOLD=${ORACLE_DEVIATION_THRESHOLD:-"50"}

# Get deployer address
DEPLOYER_ADDRESS=$(cast wallet address --private-key "$PRIVATE_KEY" 2>/dev/null || echo "")

if [ -z "$DEPLOYER_ADDRESS" ]; then
    log_warn "Warning: Could not get deployer address. Using script default"
    DEPLOYER_ADDRESS="0x$(echo "$PRIVATE_KEY" | cut -c3-42)"
fi

ORACLE_ADDRESS=$(deploy_contract "script/DeployOracle.s.sol:DeployOracle" "Oracle Aggregator" "ORACLE_AGGREGATOR_ADDRESS")
if [ -z "$ORACLE_ADDRESS" ]; then
    log_error "Error: Failed to deploy Oracle Aggregator"
    exit 1
fi

# Step 8: Summary
log_success "=== Deployment Summary ==="
log_success "CCIP Router: ${CCIP_ROUTER}"
log_success "CCIP Fee Token: ${CCIP_FEE_TOKEN}"
log_success "WETH9: ${WETH9_ADDRESS}"
log_success "WETH10: ${WETH10_ADDRESS}"
if [ -n "$CCIPWETH9BRIDGE_ADDRESS" ]; then
    log_success "CCIPWETH9Bridge: ${CCIPWETH9BRIDGE_ADDRESS}"
fi
if [ -n "$CCIPWETH10BRIDGE_ADDRESS" ]; then
    log_success "CCIPWETH10Bridge: ${CCIPWETH10BRIDGE_ADDRESS}"
fi
log_success "Oracle Aggregator: ${ORACLE_ADDRESS}"

log_success "=== Deployment Complete ==="
log_success "All contract addresses have been updated in .env file"
