#!/usr/bin/env bash
# ============================================================
# Timmy Node — Day-to-day operations helper
# Usage: bash ops.sh <command>
# ============================================================

INFRA_DIR="/opt/timmy-node"
cd "$INFRA_DIR" 2>/dev/null || { echo "Run on the droplet, not locally"; exit 1; }

CYAN='\033[0;36m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m'

case "${1:-help}" in

  status)
    echo -e "\n${CYAN}── Docker services ──────────────────────────${NC}"
    docker compose ps

    echo -e "\n${CYAN}── Bitcoin sync ──────────────────────────────${NC}"
    docker exec bitcoin bitcoin-cli -datadir=/home/bitcoin/.bitcoin getblockchaininfo 2>/dev/null \
      | jq '{blocks, headers, verificationprogress, size_on_disk}' \
      || echo "Bitcoin not ready"

    echo -e "\n${CYAN}── LND state ─────────────────────────────────${NC}"
    docker exec lnd lncli --network=mainnet getinfo 2>/dev/null \
      | jq '{identity_pubkey, alias, num_peers, num_active_channels, synced_to_chain}' \
      || echo "LND not ready"

    echo -e "\n${CYAN}── LND wallet balance ────────────────────────${NC}"
    docker exec lnd lncli --network=mainnet walletbalance 2>/dev/null \
      | jq '{confirmed_balance, unconfirmed_balance}' \
      || true

    echo -e "\n${CYAN}── LND channel balance ───────────────────────${NC}"
    docker exec lnd lncli --network=mainnet channelbalance 2>/dev/null \
      | jq '{balance, pending_open_balance}' \
      || true
    ;;

  sync)
    watch -n 10 'docker exec bitcoin bitcoin-cli getblockchaininfo \
      | jq "{blocks, verificationprogress, size_on_disk}"'
    ;;

  logs)
    SERVICE="${2:-}"
    if [[ -z "$SERVICE" ]]; then
      docker compose logs -f --tail=50
    else
      docker compose logs -f --tail=100 "$SERVICE"
    fi
    ;;

  restart)
    SERVICE="${2:-}"
    if [[ -z "$SERVICE" ]]; then
      docker compose restart
    else
      docker compose restart "$SERVICE"
    fi
    ;;

  fund)
    echo -e "${CYAN}Your on-chain deposit address (send BTC here to fund channels):${NC}"
    docker exec lnd lncli --network=mainnet newaddress p2wkh | jq -r .address
    ;;

  channels)
    echo -e "\n${CYAN}── Active channels ───────────────────────────${NC}"
    docker exec lnd lncli --network=mainnet listchannels 2>/dev/null \
      | jq '.channels[] | {remote_pubkey, capacity, local_balance, remote_balance, active}'
    echo -e "\n${CYAN}── Pending channels ──────────────────────────${NC}"
    docker exec lnd lncli --network=mainnet pendingchannels 2>/dev/null \
      | jq '{pending_open_channels: .pending_open_channels | length, pending_closing_channels: .pending_closing_channels | length}'
    ;;

  open-channel)
    echo -e "${CYAN}Open a channel — usage:${NC}"
    echo "  bash ops.sh open-channel <peer_pubkey>@<host>:<port> <amount_sats>"
    if [[ -n "${2:-}" && -n "${3:-}" ]]; then
      docker exec lnd lncli --network=mainnet connect "$2" 2>/dev/null || true
      PUBKEY=$(echo "$2" | cut -d@ -f1)
      docker exec lnd lncli --network=mainnet openchannel \
        --node_key "$PUBKEY" \
        --local_amt "$3" \
        --push_amt 0
    fi
    ;;

  lnbits-key)
    echo -e "${CYAN}LNbits API keys for Timmy wallet:${NC}"
    grep "LNBITS" /root/node-credentials.txt 2>/dev/null || \
      echo "Check /root/node-credentials.txt — or open LNbits dashboard"
    TSHOST=$(tailscale status --json 2>/dev/null | jq -r '.Self.DNSName' | sed 's/\.$//')
    echo -e "\nLNbits dashboard: ${GREEN}https://$TSHOST${NC}"
    ;;

  update)
    echo -e "${YELLOW}Pulling latest Docker images...${NC}"
    docker compose pull
    docker compose up -d
    ok "Done"
    ;;

  backup)
    BACKUP_FILE="/root/lnd-backup-$(date +%Y%m%d-%H%M%S).tar.gz"
    echo -e "${CYAN}Backing up LND channel state to $BACKUP_FILE${NC}"
    tar -czf "$BACKUP_FILE" -C /data/lnd .
    echo -e "${GREEN}Backup saved. Copy this file off the server:${NC}"
    echo "  scp root@<node>:$BACKUP_FILE ./lnd-backup.tar.gz"
    ;;

  sweep)
    SWEEP_CONF="$INFRA_DIR/sweep.conf"
    SWEEP_LOG="/var/log/timmy-sweep.log"

    STATE_FILE="$INFRA_DIR/sweep-state"
    ADDR_LIST_FILE="$INFRA_DIR/sweep-addresses.txt"

    echo -e "\n${CYAN}── Sweep config ──────────────────────────────${NC}"
    if [[ -f "$SWEEP_CONF" ]]; then
      SWEEP_MODE="static"; COLD_ADDRESS=""; XPUB=""
      KEEP_SATS=300000; MIN_SWEEP=50000
      SWEEP_FREQ_LABEL="daily at 3am UTC"; SWEEP_CRON="0 3 * * *"
      source "$SWEEP_CONF"
      echo "  Mode         : ${SWEEP_MODE}"
      case "$SWEEP_MODE" in
        static)
          echo "  Destination  : ${COLD_ADDRESS:-(not set — sweep disabled)}"
          ;;
        list)
          COUNT=$(grep -c '[^[:space:]]' "$ADDR_LIST_FILE" 2>/dev/null || echo 0)
          NEXT_INDEX=0; [[ -f "$STATE_FILE" ]] && source "$STATE_FILE"
          REMAINING=$(( COUNT - NEXT_INDEX ))
          echo "  Addresses    : ${COUNT} total, ${REMAINING} remaining (next: index ${NEXT_INDEX})"
          NEXT_ADDR=$(sed -n "$((NEXT_INDEX + 1))p" "$ADDR_LIST_FILE" 2>/dev/null | tr -d '[:space:]')
          [[ -n "$NEXT_ADDR" ]] && echo "  Next address : ${NEXT_ADDR}"
          ;;
        xpub)
          NEXT_INDEX=0; [[ -f "$STATE_FILE" ]] && source "$STATE_FILE"
          echo "  xpub         : ${XPUB:0:30}..."
          echo "  Next index   : ${NEXT_INDEX}"
          ;;
      esac
      echo "  Keep on-chain: ${KEEP_SATS} sats"
      echo "  Min to sweep : ${MIN_SWEEP} sats"
      echo "  Frequency    : ${SWEEP_FREQ_LABEL}"
    else
      echo -e "  ${YELLOW}No sweep.conf found — sweep is disabled${NC}"
      echo "  To configure: bash ops.sh configure-sweep"
    fi

    echo -e "\n${CYAN}── Current on-chain balance ──────────────────${NC}"
    docker exec lnd lncli --network=mainnet walletbalance 2>/dev/null \
      | jq '{confirmed_balance, unconfirmed_balance}' \
      || echo "  LND not ready"

    echo -e "\n${CYAN}── Last 5 sweep log entries ──────────────────${NC}"
    if [[ -f "$SWEEP_LOG" && -s "$SWEEP_LOG" ]]; then
      tail -5 "$SWEEP_LOG"
    else
      echo "  No sweep activity yet"
    fi
    echo ""
    ;;

  configure-sweep)
    SWEEP_CONF="$INFRA_DIR/sweep.conf"
    STATE_FILE="$INFRA_DIR/sweep-state"
    ADDR_LIST_FILE="$INFRA_DIR/sweep-addresses.txt"

    # Load current values as defaults
    SWEEP_MODE="static"; COLD_ADDRESS=""; XPUB=""
    KEEP_SATS=300000; MIN_SWEEP=50000
    SWEEP_CRON="0 3 * * *"; SWEEP_FREQ_LABEL="daily at 3am UTC"
    [[ -f "$SWEEP_CONF" ]] && source "$SWEEP_CONF"

    echo -e "\n${CYAN}══════════════════════════════════════════${NC}"
    echo -e "${CYAN} Configure Auto-Sweep  (Enter = keep current)${NC}"
    echo -e "${CYAN}══════════════════════════════════════════${NC}\n"

    # ── Destination mode ──────────────────────────────────────
    echo -e "  Current destination mode: ${YELLOW}${SWEEP_MODE}${NC}"
    echo "  Choose a destination mode:"
    echo "    1) Single address  — same address every sweep"
    echo "    2) Address list    — rotate through a list of addresses (no reuse)"
    echo "    3) xpub            — derive a fresh address each sweep (no reuse)"
    read -rp "  Choice [1-3, Enter to keep]: " MODE_CHOICE
    case "$MODE_CHOICE" in
      1) SWEEP_MODE="static" ;;
      2) SWEEP_MODE="list" ;;
      3) SWEEP_MODE="xpub" ;;
    esac

    # ── Mode-specific inputs ──────────────────────────────────
    case "$SWEEP_MODE" in
      static)
        echo -e "\n  Current cold address: ${YELLOW}${COLD_ADDRESS:-(none)}${NC}"
        read -rp "  New cold address (bc1q... / 1... / 3...): " INPUT
        [[ -n "$INPUT" ]] && COLD_ADDRESS="$INPUT"
        XPUB=""
        ;;

      list)
        if [[ -f "$ADDR_LIST_FILE" ]]; then
          COUNT=$(grep -c '[^[:space:]]' "$ADDR_LIST_FILE" || true)
          echo -e "\n  Current address list: ${YELLOW}${COUNT} address(es) in $ADDR_LIST_FILE${NC}"
        else
          echo -e "\n  No address list found yet."
        fi
        NEXT_INDEX=0
        [[ -f "$STATE_FILE" ]] && source "$STATE_FILE"
        echo "  Current position: index ${NEXT_INDEX}"
        echo ""
        echo "  Paste cold addresses now (one per line, blank line when done)."
        echo "  These REPLACE the existing list. Leave blank to keep current list."
        echo ""
        NEW_ADDRS=()
        while IFS= read -rp "  > " ADDR_INPUT && [[ -n "$ADDR_INPUT" ]]; do
          ADDR_INPUT=$(echo "$ADDR_INPUT" | tr -d '[:space:]')
          [[ -n "$ADDR_INPUT" ]] && NEW_ADDRS+=("$ADDR_INPUT")
        done
        if (( ${#NEW_ADDRS[@]} > 0 )); then
          printf '%s\n' "${NEW_ADDRS[@]}" > "$ADDR_LIST_FILE"
          chmod 600 "$ADDR_LIST_FILE"
          echo "NEXT_INDEX=0" > "$STATE_FILE"
          chmod 600 "$STATE_FILE"
          echo -e "  ${GREEN}Saved ${#NEW_ADDRS[@]} addresses. Index reset to 0.${NC}"
        else
          echo "  Kept existing address list."
        fi
        COLD_ADDRESS=""; XPUB=""
        ;;

      xpub)
        echo -e "\n  Current xpub: ${YELLOW}${XPUB:-(none)}${NC}"
        echo "  Paste your account xpub (from Sparrow, Coldcard, etc. — account-level, not master)."
        read -rp "  xpub: " INPUT
        if [[ -n "$INPUT" ]]; then
          XPUB="$INPUT"
          echo "NEXT_INDEX=0" > "$STATE_FILE"
          chmod 600 "$STATE_FILE"
          echo -e "  ${GREEN}xpub saved. Derivation index reset to 0.${NC}"
        fi
        COLD_ADDRESS=""
        ;;
    esac

    # ── Keep threshold ────────────────────────────────────────
    echo -e "\n  Current keep-on-chain threshold: ${YELLOW}${KEEP_SATS} sats${NC}"
    read -rp "  New keep threshold (sats): " INPUT
    [[ "$INPUT" =~ ^[0-9]+$ ]] && KEEP_SATS="$INPUT"

    # ── Min sweep floor ───────────────────────────────────────
    echo -e "\n  Current minimum sweep amount: ${YELLOW}${MIN_SWEEP} sats${NC}"
    read -rp "  New minimum sweep (sats): " INPUT
    [[ "$INPUT" =~ ^[0-9]+$ ]] && MIN_SWEEP="$INPUT"

    # ── Frequency ─────────────────────────────────────────────
    echo -e "\n  Current frequency: ${YELLOW}${SWEEP_FREQ_LABEL}${NC}"
    echo "  Choose a new frequency (Enter to keep current):"
    echo "    1) Hourly"
    echo "    2) Every 6 hours"
    echo "    3) Daily at 3am UTC"
    echo "    4) Weekly (Sunday 3am UTC)"
    read -rp "  Choice [1-4]: " FREQ_CHOICE
    case "$FREQ_CHOICE" in
      1) SWEEP_CRON="0 * * * *";    SWEEP_FREQ_LABEL="hourly" ;;
      2) SWEEP_CRON="0 */6 * * *";  SWEEP_FREQ_LABEL="every 6 hours" ;;
      3) SWEEP_CRON="0 3 * * *";    SWEEP_FREQ_LABEL="daily at 3am UTC" ;;
      4) SWEEP_CRON="0 3 * * 0";    SWEEP_FREQ_LABEL="weekly (Sunday 3am UTC)" ;;
    esac

    # ── Write sweep.conf ──────────────────────────────────────
    cat > "$SWEEP_CONF" <<CONF
# Timmy Node — Auto-sweep configuration
# Edit manually or run: bash ops.sh configure-sweep

SWEEP_MODE="$SWEEP_MODE"
COLD_ADDRESS="$COLD_ADDRESS"
XPUB="$XPUB"
KEEP_SATS=$KEEP_SATS
MIN_SWEEP=$MIN_SWEEP
SWEEP_CRON="$SWEEP_CRON"
SWEEP_FREQ_LABEL="$SWEEP_FREQ_LABEL"
CONF
    chmod 600 "$SWEEP_CONF"

    # ── Reinstall cron ────────────────────────────────────────
    crontab -l 2>/dev/null | grep -v "timmy-node.*sweep" | crontab - || true
    (crontab -l 2>/dev/null; echo "# Timmy Node — auto-sweep ($SWEEP_FREQ_LABEL)") | crontab -
    (crontab -l 2>/dev/null; echo "$SWEEP_CRON bash $INFRA_DIR/sweep.sh > /dev/null 2>&1") | crontab -

    echo -e "\n${GREEN}Sweep configured:${NC}"
    echo "  Mode         : ${SWEEP_MODE}"
    case "$SWEEP_MODE" in
      static) echo "  Destination  : ${COLD_ADDRESS:-(not set — sweep disabled)}" ;;
      list)
        COUNT=$(grep -c '[^[:space:]]' "$ADDR_LIST_FILE" 2>/dev/null || echo 0)
        NEXT_INDEX=0; [[ -f "$STATE_FILE" ]] && source "$STATE_FILE"
        echo "  Addresses    : ${COUNT} total, starting at index ${NEXT_INDEX}"
        ;;
      xpub)
        NEXT_INDEX=0; [[ -f "$STATE_FILE" ]] && source "$STATE_FILE"
        echo "  xpub         : ${XPUB:0:20}..."
        echo "  Next index   : ${NEXT_INDEX}"
        ;;
    esac
    echo "  Keep on-chain: ${KEEP_SATS} sats"
    echo "  Min to sweep : ${MIN_SWEEP} sats"
    echo "  Frequency    : ${SWEEP_FREQ_LABEL}"
    echo ""
    echo -e "  Run now to test: ${CYAN}bash ops.sh run-sweep${NC}"
    echo ""
    ;;

  run-sweep)
    echo -e "${CYAN}Running sweep now...${NC}"
    bash "$INFRA_DIR/sweep.sh"
    ;;

  relay:logs)
    echo -e "${CYAN}Tailing strfry relay logs (Ctrl-C to stop)...${NC}"
    docker compose logs -f --tail=100 strfry relay-policy
    ;;

  relay:restart)
    echo -e "${CYAN}Restarting Nostr relay services...${NC}"
    docker compose restart relay-policy
    sleep 2
    docker compose restart strfry
    echo -e "${GREEN}Done — relay services restarted.${NC}"
    docker compose ps relay-policy strfry
    ;;

  relay:status)
    echo -e "\n${CYAN}── Nostr relay ───────────────────────────────${NC}"
    docker compose ps relay-policy strfry
    echo -e "\n${CYAN}── relay-policy health ───────────────────────${NC}"
    docker exec relay-policy wget -qO- http://localhost:3080/health 2>/dev/null \
      | (command -v jq >/dev/null 2>&1 && jq . || cat) \
      || echo "relay-policy not ready"
    ;;

  help|*)
    echo -e "\n${CYAN}Timmy Node operations:${NC}"
    echo ""
    echo "  bash ops.sh status          — overview of all services + balances"
    echo "  bash ops.sh sync            — watch Bitcoin chain sync progress"
    echo "  bash ops.sh logs [service]  — tail logs (bitcoin | lnd | lnbits)"
    echo "  bash ops.sh restart [svc]   — restart a service or all services"
    echo "  bash ops.sh fund            — get on-chain deposit address"
    echo "  bash ops.sh channels        — list open and pending channels"
    echo "  bash ops.sh open-channel    — open a Lightning channel"
    echo "  bash ops.sh lnbits-key      — show LNBITS_URL and API key for Replit"
    echo "  bash ops.sh update          — pull latest Docker images"
    echo "  bash ops.sh backup          — backup LND channel state"
    echo "  bash ops.sh sweep           — show sweep config, balance, and last sweep log"
    echo "  bash ops.sh configure-sweep — interactively set address, thresholds, frequency"
    echo "  bash ops.sh run-sweep       — run sweep immediately (outside of cron schedule)"
    echo ""
    echo "  bash ops.sh relay:logs      — tail strfry + relay-policy logs"
    echo "  bash ops.sh relay:restart   — restart relay-policy then strfry (safe order)"
    echo "  bash ops.sh relay:status    — show relay container status + health"
    echo ""
    ;;

esac
