#!/usr/bin/env bash
# Deployment tag parsing and interactive prompts.
# Usage: source "$SCRIPT_DIR/lib/deployment/prompts.sh"
# Provides: parse_fund_tags, prompt_fund_amounts, eth_to_wei, parse_phase_tags

# Resolve lib and project paths when sourced
_LIB_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
[[ -z "${PROJECT_ROOT:-}" ]] && PROJECT_ROOT="$(cd "$_LIB_DIR/../.." && pwd)"

# Convert ETH string to wei (supports "1.5", "1.5eth", "1000000000000000000" or "1000000000000000000wei")
eth_to_wei() {
  local val="${1:-0}"
  if [[ -z "$val" || "$val" == "0" ]]; then
    echo "0"
    return 0
  fi
  if [[ "$val" == *wei ]]; then
    echo "${val%wei}"
    return 0
  fi
  if [[ "$val" == *eth ]]; then
    val="${val%eth}"
  fi
  if command -v cast &>/dev/null; then
    cast to-wei "$val" ether 2>/dev/null || echo "0"
  else
    # Fallback: 1 eth = 1e18 (bash can't do float well; use bc/python if available)
    if command -v python3 &>/dev/null; then
      python3 -c "import math; print(int(float('$val') * 10**18))" 2>/dev/null || echo "0"
    else
      echo "0"
    fi
  fi
}

# Parse --eth, --weth, --eth-wei, --weth-wei, --dry-run from "$@".
# Sets: FUND_ETH_AMOUNT_WEI, FUND_WETH_AMOUNT_WEI (exported), DRY_RUN=1 if --dry-run.
# Consumed args are removed from the array; use parse_fund_tags "${@}" before other parsers.
parse_fund_tags() {
  export FUND_ETH_AMOUNT_WEI="${FUND_ETH_AMOUNT_WEI:-0}"
  export FUND_WETH_AMOUNT_WEI="${FUND_WETH_AMOUNT_WEI:-0}"
  export DRY_RUN="${DRY_RUN:-0}"
  local args=()
  while [[ $# -gt 0 ]]; do
    case "$1" in
      --eth)
        FUND_ETH_AMOUNT_WEI="$(eth_to_wei "${2:-0}")"
        shift 2
        ;;
      --weth)
        FUND_WETH_AMOUNT_WEI="$(eth_to_wei "${2:-0}")"
        shift 2
        ;;
      --eth-wei)
        FUND_ETH_AMOUNT_WEI="${2:-0}"
        shift 2
        ;;
      --weth-wei)
        FUND_WETH_AMOUNT_WEI="${2:-0}"
        shift 2
        ;;
      --dry-run)
        DRY_RUN=1
        shift
        ;;
      *)
        args+=("$1")
        shift
        ;;
    esac
  done
  # Return unconsumed args (caller can set PARSE_FUND_TAGS_REMAINING=( "${args[@]}" ) or use as needed)
  PARSE_FUND_TAGS_REMAINING=("${args[@]}")
}

# Interactive prompt for ETH/WETH amounts (only if both are 0 and stdin is a TTY).
# Sets FUND_ETH_AMOUNT_WEI and FUND_WETH_AMOUNT_WEI (exported).
prompt_fund_amounts() {
  local eth_wei="${FUND_ETH_AMOUNT_WEI:-0}"
  local weth_wei="${FUND_WETH_AMOUNT_WEI:-0}"
  if [[ -n "$eth_wei" && "$eth_wei" != "0" ]] || [[ -n "$weth_wei" && "$weth_wei" != "0" ]]; then
    return 0
  fi
  if [[ ! -t 0 ]]; then
    return 0
  fi
  echo "G4: Fund mainnet Liquidity Pool (ETH and/or WETH)."
  read -r -p "ETH amount (e.g. 1.5 or 0 to skip): " eth_input
  read -r -p "WETH amount (e.g. 0.5 or 0 to skip): " weth_input
  export FUND_ETH_AMOUNT_WEI="$(eth_to_wei "${eth_input:-0}")"
  export FUND_WETH_AMOUNT_WEI="$(eth_to_wei "${weth_input:-0}")"
}

# Parse phase tags: g1, g2, g3, g2g3, g4 from "$@".
# Sets: RUN_G1, RUN_G2G3, RUN_G4 (0 or 1). Unconsumed args left in PARSE_PHASE_TAGS_REMAINING.
parse_phase_tags() {
  RUN_G1=0
  RUN_G2G3=0
  RUN_G4=0
  local args=()
  for arg in "$@"; do
    case "${arg,,}" in
      g1) RUN_G1=1 ;;
      g2|g3|g2g3) RUN_G2G3=1 ;;
      g4) RUN_G4=1 ;;
      *) args+=("$arg") ;;
    esac
  done
  # If no phase given, run all
  if [[ "$RUN_G1" -eq 0 && "$RUN_G2G3" -eq 0 && "$RUN_G4" -eq 0 ]]; then
    RUN_G1=1
    RUN_G2G3=1
    RUN_G4=1
  fi
  PARSE_PHASE_TAGS_REMAINING=("${args[@]}")
}

# Canonical L2 list for deploy-pmm, deploy-trustless, fund-ccip, etc.
L2_CHAIN_NAMES=( BSC POLYGON BASE OPTIMISM ARBITRUM AVALANCHE CRONOS GNOSIS CELO WEMIX )

# Parse --chain <name> [<name> ...] from "$@". Names case-insensitive (bsc, BSC, Polygon, etc.).
# Sets CHAIN_FILTER=() (empty = all) or CHAIN_FILTER=( BSC POLYGON ... ). Unconsumed in PARSE_CHAIN_FILTER_REMAINING.
normalize_chain_name() {
  case "${1^^}" in
    BSC) echo BSC ;;
    POLYGON) echo POLYGON ;;
    BASE) echo BASE ;;
    OPTIMISM) echo OPTIMISM ;;
    ARBITRUM) echo ARBITRUM ;;
    AVALANCHE) echo AVALANCHE ;;
    CRONOS) echo CRONOS ;;
    GNOSIS) echo GNOSIS ;;
    CELO) echo CELO ;;
    WEMIX) echo WEMIX ;;
    ETH|ETHEREUM|MAINNET) echo ETH ;;
    138|CHAIN138|CHAIN_138) echo CHAIN138 ;;
    *) echo "" ;;
  esac
}

parse_chain_filter() {
  CHAIN_FILTER=()
  local args=()
  local collecting=0
  for arg in "$@"; do
    if [[ "$arg" == "--chain" ]]; then
      collecting=1
    elif [[ "$collecting" -eq 1 ]]; then
      local n; n="$(normalize_chain_name "$arg")"
      if [[ -n "$n" ]]; then
        CHAIN_FILTER+=("$n")
      else
        args+=("$arg")
        collecting=0
      fi
    else
      args+=("$arg")
    fi
  done
  PARSE_CHAIN_FILTER_REMAINING=("${args[@]}")
}

# Parse --lockbox / --no-lockbox. Sets TRUSTLESS_DEPLOY_LOCKBOX=1 or 0. Default from env or 0.
# Unconsumed in PARSE_LOCKBOX_REMAINING.
parse_lockbox_tag() {
  TRUSTLESS_DEPLOY_LOCKBOX="${TRUSTLESS_DEPLOY_LOCKBOX:-0}"
  local args=()
  for arg in "$@"; do
    case "$arg" in
      --lockbox) TRUSTLESS_DEPLOY_LOCKBOX=1; ;;
      --no-lockbox) TRUSTLESS_DEPLOY_LOCKBOX=0; ;;
      *) args+=("$arg") ;;
    esac
  done
  PARSE_LOCKBOX_REMAINING=("${args[@]}")
}

# Parse --link <amount> (ETH or wei if --link-wei), --dry-run, --cap-to-deployer.
# Sets LINK_AMOUNT_WEI, DRY_RUN, CAP_LINK_TO_DEPLOYER_BALANCE (0/1).
# Default LINK_AMOUNT_WEI 10e18 (10 LINK) when unset. Unconsumed in PARSE_LINK_TAGS_REMAINING.
# --cap-to-deployer: callers (e.g. fund-ccip-bridges-with-link.sh) cap each bridge transfer to
# min(LINK_AMOUNT_WEI, deployer_LINK_balance // bridges_on_that_chain).
link_to_wei() {
  local val="${1:-0}"
  if [[ -z "$val" || "$val" == "0" ]]; then echo "0"; return; fi
  if [[ "$val" == *wei ]]; then echo "${val%wei}"; return; fi
  if command -v cast &>/dev/null; then
    cast to-wei "$val" ether 2>/dev/null || echo "0"
  elif command -v python3 &>/dev/null; then
    python3 -c "import math; print(int(float('$val') * 10**18))" 2>/dev/null || echo "0"
  else
    echo "0"
  fi
}

parse_link_tags() {
  export LINK_AMOUNT_WEI="${LINK_AMOUNT_WEI:-10000000000000000000}"
  export DRY_RUN="${DRY_RUN:-0}"
  export CAP_LINK_TO_DEPLOYER_BALANCE="${CAP_LINK_TO_DEPLOYER_BALANCE:-0}"
  local args=()
  local i=0
  local argv=("$@")
  while [[ $i -lt ${#argv[@]} ]]; do
    local a="${argv[$i]}"
    case "$a" in
      --link)
        [[ $((i+1)) -lt ${#argv[@]} ]] && LINK_AMOUNT_WEI="$(link_to_wei "${argv[$((i+1))]}")"
        i=$((i+2)); ;;
      --link-wei)
        [[ $((i+1)) -lt ${#argv[@]} ]] && LINK_AMOUNT_WEI="${argv[$((i+1))]}"
        i=$((i+2)); ;;
      --cap-to-deployer) CAP_LINK_TO_DEPLOYER_BALANCE=1; i=$((i+1)); ;;
      --dry-run) DRY_RUN=1; i=$((i+1)); ;;
      *) args+=("$a"); i=$((i+1)); ;;
    esac
  done
  PARSE_LINK_TAGS_REMAINING=("${args[@]}")
}

# Parse --dry-run only. Sets DRY_RUN=1. Unconsumed in PARSE_DRY_RUN_REMAINING.
parse_dry_run_tag() {
  DRY_RUN="${DRY_RUN:-0}"
  local args=()
  for arg in "$@"; do
    if [[ "$arg" == "--dry-run" ]]; then DRY_RUN=1; else args+=("$arg"); fi
  done
  PARSE_DRY_RUN_REMAINING=("${args[@]}")
}

# Parse --deploy. Sets DO_DEPLOY=1. Unconsumed in PARSE_DEPLOY_REMAINING.
parse_deploy_tag() {
  DO_DEPLOY="${DO_DEPLOY:-0}"
  local args=()
  for arg in "$@"; do
    if [[ "$arg" == "--deploy" ]]; then DO_DEPLOY=1; else args+=("$arg"); fi
  done
  PARSE_DEPLOY_REMAINING=("${args[@]}")
}

# Parse --delay <seconds>. Sets DELAY_BETWEEN_CHAINS. Unconsumed in PARSE_DELAY_REMAINING.
parse_delay_tag() {
  DELAY_BETWEEN_CHAINS="${DELAY_BETWEEN_CHAINS:-45}"
  local args=()
  local i=0
  local argv=("$@")
  while [[ $i -lt ${#argv[@]} ]]; do
    if [[ "${argv[$i]}" == "--delay" && $((i+1)) -lt ${#argv[@]} ]]; then
      DELAY_BETWEEN_CHAINS="${argv[$((i+1))]}"
      i=$((i+2))
    else
      args+=("${argv[$i]}")
      i=$((i+1))
    fi
  done
  PARSE_DELAY_REMAINING=("${args[@]}")
}
