#!/usr/bin/env bash
# =============================================================================
# IOTA Web Guardian — Interactive Setup Wizard
#
# Guides the user through the entire setup process step by step.
# Each step explains what it does, executes it, and proposes the next action.
#
# Usage:
#   ./scripts/wizard.sh
# =============================================================================

set -euo pipefail
cd "$(dirname "$0")/.."

# ─── Colors & Formatting ─────────────────────────────────────────────────────

BOLD='\033[1m'
DIM='\033[2m'
ITALIC='\033[3m'
RESET='\033[0m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
YELLOW='\033[1;33m'
MAGENTA='\033[1;35m'
WHITE='\033[1;37m'
RED='\033[0;31m'
BG_GREEN='\033[42m'
BG_BLUE='\033[44m'
BG_YELLOW='\033[43m'
BG_CYAN='\033[46m'

# ─── Helpers ──────────────────────────────────────────────────────────────────

W=78

line() {
    local text="$1"
    local visible
    visible=$(echo -e "$text" | sed 's/\x1b\[[0-9;]*m//g')
    local len=${#visible}
    local pad=$((W - len))
    if [ $pad -lt 0 ]; then pad=0; fi
    printf "${GREEN}║${RESET}%b%*s${GREEN}║${RESET}\n" "$text" "$pad" ""
}

TOP="${GREEN}╔$(printf '═%.0s' $(seq 1 $W))╗${RESET}"
MID="${GREEN}╠$(printf '═%.0s' $(seq 1 $W))╣${RESET}"
BOT="${GREEN}╚$(printf '═%.0s' $(seq 1 $W))╝${RESET}"

clear_screen() {
    printf '\033[2J\033[H'
}

banner() {
    echo -e "$TOP"
    line ""
    line "  ${WHITE}${BOLD}IOTA Web Guardian${RESET}  ${DIM}— Interactive Setup Wizard${RESET}"
    line ""
    line "  ${DIM}Protect content creators from uncompensated AI scraping.${RESET}"
    line "  ${DIM}DID + Verifiable Credentials + IOTA Micropayments.${RESET}"
    line ""
    echo -e "$BOT"
}

step_header() {
    local num="$1"
    local title="$2"
    local desc="$3"
    echo ""
    echo -e "$TOP"
    line ""
    line "  ${BG_BLUE}${WHITE}${BOLD} STEP ${num} ${RESET}  ${WHITE}${BOLD}${title}${RESET}"
    line ""
    line "  ${DIM}${desc}${RESET}"
    line ""
    echo -e "$BOT"
}

success_box() {
    local msg="$1"
    echo ""
    echo -e "$TOP"
    line ""
    line "  ${GREEN}${BOLD}✓${RESET} ${msg}"
    line ""
    echo -e "$BOT"
}

warn_box() {
    local msg="$1"
    echo ""
    echo -e "${YELLOW}⚠${RESET}  ${YELLOW}${msg}${RESET}"
}

action_required() {
    local msg="$1"
    echo ""
    echo -e "$TOP"
    line ""
    line "  ${BG_YELLOW}${WHITE}${BOLD} ACTION REQUIRED ${RESET}"
    line ""
    line "  ${msg}"
    line ""
    echo -e "$BOT"
}

wait_for_user() {
    local msg="${1:-Press ENTER to continue...}"
    echo ""
    echo -ne "  ${CYAN}${BOLD}▸${RESET} ${msg} "
    read -r
}

wait_or_skip() {
    local msg="${1:-Press ENTER to continue, or 's' to skip...}"
    echo ""
    echo -ne "  ${CYAN}${BOLD}▸${RESET} ${msg} "
    read -r answer
    if [ "$answer" = "s" ] || [ "$answer" = "S" ]; then
        return 1
    fi
    return 0
}

run_cmd() {
    local desc="$1"
    shift
    echo ""
    echo -e "  ${DIM}Running:${RESET} ${CYAN}$*${RESET}"
    echo -e "  ${DIM}$(printf '─%.0s' $(seq 1 68))${RESET}"
    "$@" 2>&1 | sed 's/^/  /'
    local exit_code=${PIPESTATUS[0]}
    echo -e "  ${DIM}$(printf '─%.0s' $(seq 1 68))${RESET}"
    if [ $exit_code -eq 0 ]; then
        echo -e "  ${GREEN}✓${RESET} ${desc}"
    else
        echo -e "  ${RED}✗${RESET} ${desc} ${RED}(exit code: ${exit_code})${RESET}"
    fi
    return $exit_code
}

# Run a command with a spinner shown while it executes
spin_cmd() {
    local msg="$1"
    shift
    local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
    local log_file
    log_file=$(mktemp)

    # Run command in background
    "$@" > "$log_file" 2>&1 &
    local pid=$!
    local i=0

    # Show spinner
    while kill -0 "$pid" 2>/dev/null; do
        printf "\r  ${CYAN}%s${RESET} %s" "${frames[$((i % ${#frames[@]}))]}" "$msg"
        i=$((i + 1))
        sleep 0.15
    done

    wait "$pid"
    local exit_code=$?

    # Clear spinner line and show result
    printf "\r%*s\r" 80 ""
    if [ $exit_code -eq 0 ]; then
        echo -e "  ${GREEN}✓${RESET} ${msg}"
    else
        echo -e "  ${RED}✗${RESET} ${msg}"
        # Show last 5 lines of output on failure
        echo -e "  ${DIM}$(tail -5 "$log_file" | sed 's/^/    /')${RESET}"
    fi
    rm -f "$log_file"
    return $exit_code
}

check_command() {
    if command -v "$1" &> /dev/null; then
        echo -e "  ${GREEN}✓${RESET} ${1} found: ${DIM}$(command -v "$1")${RESET}"
        return 0
    else
        echo -e "  ${RED}✗${RESET} ${1} not found"
        return 1
    fi
}

# Suppress "Next steps" boxes in sub-scripts
export WIZARD_MODE=1

CURRENT_STEP=0
TOTAL_STEPS=9

next_step() {
    CURRENT_STEP=$((CURRENT_STEP + 1))
    echo ""
    echo -e "  ${DIM}────────────────────────────────────────────────────────────${RESET}"
    echo -e "  ${DIM}Progress: ${CURRENT_STEP}/${TOTAL_STEPS}${RESET}"
    if [ $CURRENT_STEP -lt $TOTAL_STEPS ]; then
        wait_for_user "Press ENTER for the next step..."
    fi
}

# ─── Main ─────────────────────────────────────────────────────────────────────

clear_screen
banner
echo ""
echo -e "  This wizard will guide you through the complete setup of"
echo -e "  IOTA Web Guardian. Each step will be explained before execution."
echo ""
echo -e "  ${DIM}You can press 's' to skip any step if already completed.${RESET}"
wait_for_user "Press ENTER to begin..."

# ─── Clean Slate ────────────────────────────────────────────────────────────
# Stop any previously running project containers so we start fresh.
# docker compose down only affects services in this project's compose file.
echo ""
if docker info > /dev/null 2>&1; then
    spin_cmd "Stopping any previous project containers..." docker compose down --remove-orphans
else
    echo -e "  ${DIM}Docker not running — skipping container cleanup.${RESET}"
fi

# ─── Step 1: Prerequisites Check ─────────────────────────────────────────────

clear_screen
step_header "1" "Prerequisites Check" "Verifying that all required tools are installed."

echo ""
echo -e "  ${BOLD}Checking required tools:${RESET}"
echo ""

MISSING=0
check_command "cargo" || MISSING=$((MISSING + 1))
check_command "iota" || MISSING=$((MISSING + 1))
check_command "docker" || MISSING=$((MISSING + 1))
check_command "pnpm" || MISSING=$((MISSING + 1))
check_command "node" || MISSING=$((MISSING + 1))

echo ""

if [ $MISSING -gt 0 ]; then
    warn_box "${MISSING} tool(s) missing. Install them before continuing (see README)."
    echo ""
    echo -e "  ${DIM}Rust:   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh${RESET}"
    echo -e "  ${DIM}IOTA:   cargo install --git https://github.com/iotaledger/iota.git --tag v1.17.2 iota${RESET}"
    echo -e "  ${DIM}Docker: https://docs.docker.com/get-docker/${RESET}"
    echo -e "  ${DIM}pnpm:   npm install -g pnpm${RESET}"
    echo -e "  ${DIM}Node:   https://nodejs.org/${RESET}"
    echo ""
    wait_for_user "Install missing tools, then press ENTER to re-check (or 's' to skip)..."
else
    success_box "All prerequisites satisfied"
fi

next_step

# ─── Step 2: Build & Start Services ──────────────────────────────────────────

clear_screen
step_header "2" "Build & Start All Services" "Starts all Docker containers. First build takes 5-15 min."

echo ""
echo -e "  ${BOLD}Checking Docker...${RESET}"
if ! docker info > /dev/null 2>&1; then
    warn_box "Docker is not running. Please start Docker Desktop first."
    wait_for_user "Press ENTER when Docker Desktop is ready..."
    if ! docker info > /dev/null 2>&1; then
        echo -e "  ${RED}Docker still not available. Start it and re-run the wizard.${RESET}"
        exit 1
    fi
fi
echo -e "  ${GREEN}✓${RESET} Docker is running"

echo ""
echo -e "  ${BOLD}Services that will be started:${RESET}"
echo -e "  ${DIM}CVS (8081), x402 (8082), Guardian (8080)${RESET}"
echo -e "  ${DIM}Super Certifier (8083/5173), Certifier (8084/5174)${RESET}"
echo -e "  ${DIM}Registration App (8085/5175), WordPress (8090)${RESET}"

if wait_or_skip "Press ENTER to start docker compose, or 's' to skip..."; then
    spin_cmd "Building and starting Docker services (this may take a few minutes)..." docker compose up --build -d
    echo ""
    spin_cmd "Setting up WordPress (admin user, demo content, plugin)..." docker compose run --rm wordpress-init
else
    echo -e "  ${DIM}Skipped.${RESET}"
fi

next_step

# ─── Step 3: Initialize Environment + Configure WordPress ────────────────────

clear_screen
step_header "3" "Initialize Environment" "Creates .env, funds wallet, and configures WordPress."

if wait_or_skip "Press ENTER to run init-env.sh, or 's' to skip..."; then
    chmod +x scripts/*.sh 2>/dev/null || true
    ./scripts/init-env.sh
fi

# WordPress is already running from step 2 — configure the wallet address now
WALLET_ADDR=$(grep "^GUARDIAN_PAYMENT_RECIPIENT=" .env 2>/dev/null | cut -d= -f2 || echo "")

if [ -n "$WALLET_ADDR" ]; then
    echo ""
    echo -e "$TOP"
    line ""
    line "  ${GREEN}${BOLD}✓${RESET} .env created  ${DIM}(IOTA Testnet)${RESET}"
    line ""
    echo -e "$MID"
    line ""
    line "  ${BG_YELLOW}${WHITE}${BOLD} ACTION REQUIRED ${RESET}"
    line ""
    line "  Your wallet address:"
    line "  ${MAGENTA}${BOLD}${WALLET_ADDR}${RESET}"
    line ""
    line "  1. Open ${CYAN}http://localhost:8090/wp-admin/${RESET}  ${DIM}(admin / admin)${RESET}"
    line "  2. Go to ${WHITE}${BOLD}IOTA Guardian > Settings > Recipient Address${RESET}"
    line "  3. Paste the address above and click ${WHITE}${BOLD}Save Settings${RESET}"
    line ""
    echo -e "$BOT"

    wait_for_user "Press ENTER when you've saved the wallet address..."
    success_box "Environment initialized and WordPress configured"
else
    warn_box "No wallet address found in .env"
fi

next_step

# ─── Step 4: Deploy Identity Package ─────────────────────────────────────────

clear_screen
step_header "4" "Deploy IOTA Identity Move Package" "Publishes the Identity package to the IOTA testnet."

if wait_or_skip "Press ENTER to deploy, or 's' to skip..."; then
    ./scripts/deploy-identity-pkg.sh

    # Restart services so they pick up the new IOTA_IDENTITY_PKG_ID from .env
    echo ""
    spin_cmd "Restarting services with new Identity Package ID..." docker compose up -d --no-build super-certifier-admin certifier-service cvs
else
    echo -e "  ${DIM}Skipped.${RESET}"
fi

next_step

# ─── Step 5: Fund Service Wallets ─────────────────────────────────────────────

clear_screen
step_header "5" "Fund Service Wallets" "Funds the gas wallets of all running services via the testnet faucet."

echo ""
echo -e "  ${DIM}Tokens take up to 1 minute to arrive after funding.${RESET}"

if wait_or_skip "Press ENTER to fund wallets, or 's' to skip..."; then
    # Wait for services to be healthy before querying their wallets
    SERVICES_READY=0
    _wait_for_services() {
        for i in $(seq 1 45); do
            if curl -sf http://localhost:8083/v1/health >/dev/null 2>&1 && \
               curl -sf http://localhost:8084/v1/health >/dev/null 2>&1; then
                return 0
            fi
            sleep 2
        done
        return 1
    }
    if spin_cmd "Waiting for services to be healthy..." _wait_for_services; then
        ./scripts/fund-services.sh
    else
        warn_box "Services not ready after 90s — skipping wallet funding."
        echo -e "  ${DIM}Re-run later: ./scripts/fund-services.sh${RESET}"
    fi
else
    echo -e "  ${DIM}Skipped.${RESET}"
fi

next_step

# ─── Step 6: Certifier Registration ──────────────────────────────────────────

clear_screen
step_header "6" "Onboard: Register Certifier" "Register a Certifier organisation in the trust chain."

echo ""
echo -e "$TOP"
line ""
line "  ${BG_YELLOW}${WHITE}${BOLD} ACTION REQUIRED ${RESET}"
line ""
line "  Open ${CYAN}http://localhost:5174/register${RESET} and:"
line ""
line "  1. Fill in ${WHITE}${BOLD}Organisation Name${RESET}, ${WHITE}${BOLD}Email${RESET}, ${WHITE}${BOLD}Jurisdiction${RESET}"
line "  2. Click ${WHITE}${BOLD}Generate Keypair${RESET}"
line "  3. ${RED}${BOLD}Download the .pem private key${RESET} — keep it safe!"
line "  4. Click ${WHITE}${BOLD}Submit Application${RESET}"
line "  5. Wait for 'Pending Approval' status"
line ""
echo -e "$BOT"

wait_for_user "Press ENTER when the registration shows 'Pending Approval'..."

echo ""
echo -e "$TOP"
line ""
line "  ${BG_YELLOW}${WHITE}${BOLD} ACTION REQUIRED ${RESET}"
line ""
line "  Open ${CYAN}http://localhost:5173${RESET} (Super Certifier Admin)"
line ""
line "  Click ${WHITE}${BOLD}Approve${RESET} on the pending certifier row."
line ""
echo -e "$BOT"

wait_for_user "Press ENTER when the certifier is approved..."
success_box "Certifier approved and DID published to IOTA Tangle"

next_step

# ─── Step 8: Publish Super Certifier DID ──────────────────────────────────────

clear_screen
step_header "7" "Publish Super Certifier DID" "Publishes the Super Certifier DID and patches .env with all DID values."

if wait_or_skip "Press ENTER to run publish-super-certifier.sh, or 's' to skip..."; then
    ./scripts/publish-super-certifier.sh
else
    echo -e "  ${DIM}Skipped.${RESET}"
fi

next_step

# ─── Step 8: Agent Setup via Web UI ───────────────────────────────────────────

clear_screen
step_header "8" "Setup & Register AI Agent" "Create agent profiles and register them via the Agent Tester UI."

echo ""

# Start the agent tester dev server silently in background
(cd apps/agent-tester && pnpm install --silent >/dev/null 2>&1 && pnpm dev --port 5176 >/dev/null 2>&1) &
TESTER_PID=$!

spin_cmd "Starting Agent Tester UI on port 5176..." sleep 5

echo ""
echo -e "$TOP"
line ""
line "  ${BG_YELLOW}${WHITE}${BOLD} ACTION REQUIRED ${RESET}"
line ""
line "  Open ${CYAN}http://localhost:5176${RESET} (Agent Tester UI)"
line ""
line "  1. Click ${WHITE}${BOLD}+ New Profile${RESET} and enter a name (e.g. ${DIM}acme-bot${RESET})"
line "  2. Click ${WHITE}${BOLD}Create${RESET} — the agent keypair is generated automatically"
line "  3. Click ${WHITE}${BOLD}Register Agent${RESET} — the agent registers with the system"
line ""
line "  Then approve the agent in the Certifier Dashboard:"
line ""
line "  4. Open ${CYAN}http://localhost:5174${RESET}"
line "  5. Load your certifier key (.pem) if needed"
line "  6. Click ${WHITE}${BOLD}Approve${RESET} on the pending agent request"
line ""
line "  ${DIM}Repeat to create multiple agents if desired.${RESET}"
line ""
echo -e "$BOT"

wait_for_user "Press ENTER when at least one agent is registered and approved..."
success_box "Agent(s) registered via Agent Tester UI"

# Fund all agent wallets via testnet faucet
AGENT_PROFILES_DIR="${HOME}/.iota-guardian-agent/profiles"
if [ -d "${AGENT_PROFILES_DIR}" ]; then
    echo ""
    echo -e "  ${BOLD}Funding agent wallets via testnet faucet...${RESET}"
    echo ""
    FUNDED=0
    for config_file in "${AGENT_PROFILES_DIR}"/*/config.json; do
        [ -f "$config_file" ] || continue
        AGENT_NAME=$(basename "$(dirname "$config_file")")
        AGENT_ADDR=$(python3 -c "import json; print(json.load(open('${config_file}')).get('iota_address',''))" 2>/dev/null || echo "")
        if [ -n "${AGENT_ADDR}" ]; then
            echo -e "  Funding ${WHITE}${BOLD}${AGENT_NAME}${RESET} (${DIM}${AGENT_ADDR}${RESET})..."
            iota client faucet --address "${AGENT_ADDR}" 2>&1 | sed 's/^/    /' || \
                echo -e "    ${YELLOW}WARNING: faucet request failed${RESET}"
            FUNDED=$((FUNDED + 1))
        fi
    done
    if [ $FUNDED -gt 0 ]; then
        success_box "Funded ${FUNDED} agent wallet(s) — tokens arrive within ~1 minute"
    else
        warn_box "No agent wallet addresses found"
    fi
fi

next_step

# ─── Step 10: End-to-End Test ─────────────────────────────────────────────────

clear_screen
step_header "9" "End-to-End Demo" "Fetch protected WordPress content as an AI agent."

echo ""
echo -e "$TOP"
line ""
line "  ${BG_YELLOW}${WHITE}${BOLD} ACTION REQUIRED ${RESET}"
line ""
line "  Agent wallets were funded in the previous step."
line "  If you need more tokens, click ${WHITE}${BOLD}Fund Wallet${RESET} in the Agent Tester."
line ""
line "  Open ${CYAN}http://localhost:5176${RESET} (Agent Tester UI)"
line ""
line "  1. Select an agent profile from the dropdown"
line "  2. Pick a target page (one of the 3 demo articles)"
line "  3. Click ${WHITE}${BOLD}Fetch${RESET} and watch the pipeline flow:"
line "     ${DIM}401 challenge → VP signed → 402 payment → IOTA tx → 200 OK${RESET}"
line ""
line "  4. Click ${WHITE}${BOLD}Fetch All 3${RESET} to test all articles in sequence"
line ""
line "  5. Check ${CYAN}http://localhost:8090/wp-admin/${RESET} > ${WHITE}${BOLD}IOTA Guardian > Dashboard${RESET}"
line "     to see live charts and transaction logs"
line ""
echo -e "$BOT"

wait_for_user "Press ENTER when you've tested the E2E flow..."

# ─── Finale ───────────────────────────────────────────────────────────────────

clear_screen
echo ""
echo -e "$TOP"
line ""
line "  ${WHITE}${BOLD}Setup Complete!${RESET}"
line ""
echo -e "$MID"
line ""
line "  ${GREEN}${BOLD}✓${RESET} All services running"
line "  ${GREEN}${BOLD}✓${RESET} Certifier onboarded and DID published"
line "  ${GREEN}${BOLD}✓${RESET} AI Agent registered with Verifiable Credential"
line "  ${GREEN}${BOLD}✓${RESET} Agent wallets funded via testnet faucet"
line "  ${GREEN}${BOLD}✓${RESET} End-to-end content fetch with IOTA micropayment"
line ""
echo -e "$MID"
line ""
line "  ${BOLD}Useful links:${RESET}"
line ""
line "  ${CYAN}http://localhost:8090${RESET}         WordPress demo site"
line "  ${CYAN}http://localhost:8090/wp-admin/${RESET} WP Admin ${DIM}(admin/admin)${RESET}"
line "  ${CYAN}http://localhost:5173${RESET}         Super Certifier Admin"
line "  ${CYAN}http://localhost:5174${RESET}         Certifier Dashboard"
line "  ${CYAN}http://localhost:5175${RESET}         Agent Registration"
line "  ${CYAN}http://localhost:5176${RESET}         Agent Tester UI"
line ""
echo -e "$MID"
line ""
line "  ${BOLD}IOTA Explorer:${RESET}"
line "  ${CYAN}https://explorer.iota.org/?network=testnet${RESET}"
line ""
line "  ${BOLD}WP Dashboard:${RESET}"
line "  Open ${CYAN}IOTA Guardian > Dashboard${RESET} to see agent activity"
line "  and real-time payment charts."
line ""
echo -e "$BOT"
echo ""
