#!/bin/bash

setupApplyConfig()
{
    local payload_b64="$1"

    if [[ -z "$payload_b64" ]]; then
        isError "setupApplyConfig: no payload provided"
        return 1
    fi

    local payload
    payload=$(echo "$payload_b64" | base64 -d 2>/dev/null)
    if [[ -z "$payload" ]]; then
        isError "setupApplyConfig: failed to decode payload"
        return 1
    fi

    isHeader "Applying Setup Wizard Configuration"

    local install_name=$(echo "$payload" | jq -r '.install_name // empty')
    local timezone=$(echo "$payload" | jq -r '.timezone // empty')
    local traefik_email=$(echo "$payload" | jq -r '.traefik_email // empty')
    local domains_json=$(echo "$payload" | jq -c '.domains // []')

    if [[ -n "$install_name" ]]; then
        updateConfigOption "CFG_INSTALL_NAME" "$install_name"
        isSuccessful "Install name set to '$install_name'"
    fi

    if [[ -n "$timezone" ]]; then
        updateConfigOption "CFG_TIMEZONE" "$timezone"
        isSuccessful "Timezone set to '$timezone'"
    fi

    local domains_count=$(echo "$domains_json" | jq -r 'length')
    if [[ "$domains_count" -gt 0 ]]; then
        local i=0
        while [[ $i -lt $domains_count && $i -lt 9 ]]; do
            local d=$(echo "$domains_json" | jq -r ".[$i]")
            updateConfigOption "CFG_DOMAIN_$((i+1))" "$d"
            isSuccessful "Domain $((i+1)) set to '$d'"
            ((i++))
        done
    fi

    if [[ -n "$traefik_email" && "$traefik_email" != "null" ]]; then
        # CFG_TRAEFIK_EMAIL lives in containers/traefik/traefik.config, not in
        # the system $configs_dir, so findConfigFileForOption can't auto-locate
        # it. Point updateConfigOption at the source file directly. Traefik
        # may not be installed yet at this point — config gets copied from
        # install_containers_dir into containers_dir during the app-install
        # task, so we always update the source.
        local traefik_config_file="$install_containers_dir/traefik/traefik.config"
        if [[ -f "$traefik_config_file" ]]; then
            updateConfigOption "CFG_TRAEFIK_EMAIL" "$traefik_email" "$traefik_config_file"
            isSuccessful "Traefik LetsEncrypt email set to '$traefik_email'"
        else
            isNotice "Traefik source config not found at $traefik_config_file; skipping email write."
        fi
    fi

    # App sub-options are no longer handled here. The setup-routes backend
    # folds payload.appOptions into each install command's config_variables
    # arg (CFG_REQUIREMENT_<APP>_<OPT>=<bool>) and dockerInstallApp writes
    # them into the template config before install<App> runs.

    sourceScanFiles "libreportal_configs"
    isSuccessful "Configuration written. Selected apps will install next."
}

setupApplyFinalize()
{
    isNotice "Initializing backup engine..."
    if declare -f installResticHost >/dev/null 2>&1; then
        installResticHost
    else
        isNotice "installResticHost not loaded; backup repos will init on first backup."
    fi

    isNotice "Refreshing WebUI data snapshots so the config page reflects wizard changes..."
    if declare -f webuiLibrePortalUpdate >/dev/null 2>&1; then
        webuiLibrePortalUpdate
    else
        isNotice "webuiLibrePortalUpdate not loaded; skipping refresh."
    fi

    if declare -f webuiGenerateBackupLocations >/dev/null 2>&1; then
        webuiGenerateBackupLocations
        webuiGenerateBackupDashboard
        webuiGenerateBackupSnapshots all
        webuiGenerateBackupAppStatus
    fi

    setupWizardMarkComplete
    isSuccessful "Setup Wizard complete — your install is configured and ready."
}

setupApply()
{
    setupApplyConfig "$1" || return 1

    local payload=$(echo "$1" | base64 -d 2>/dev/null)
    local apps_json=$(echo "$payload" | jq -c '.apps // []')
    local apps_count=$(echo "$apps_json" | jq -r 'length')

    if [[ "$apps_count" -gt 0 ]]; then
        isHeader "Installing Selected Apps"
        local i=0
        while [[ $i -lt $apps_count ]]; do
            local app_name=$(echo "$apps_json" | jq -r ".[$i]")
            isNotice "[$((i+1))/$apps_count] Installing $app_name..."
            dockerInstallApp "$app_name"
            ((i++))
        done
    fi

    setupApplyFinalize
}

setupGenerateName()
{
    if declare -f generateInstallName >/dev/null 2>&1; then
        generateInstallName
    else
        echo "QuantumOtter"
    fi
}

setupCheckDomainPointsHere()
{
    local domain="$1"
    if [[ -z "$domain" ]]; then
        echo '{"matches":false,"error":"no domain"}'
        return 1
    fi

    local server_ip
    server_ip=$(dig +short +time=3 +tries=1 myip.opendns.com @resolver1.opendns.com 2>/dev/null | head -1)
    [[ -z "$server_ip" ]] && server_ip=$(hostname -I 2>/dev/null | awk '{print $1}')

    local domain_ip
    domain_ip=$(dig +short +time=3 +tries=1 "$domain" A 2>/dev/null | head -1)

    local matches="false"
    [[ -n "$server_ip" && "$server_ip" == "$domain_ip" ]] && matches="true"

    printf '{"matches":%s,"server_ip":"%s","domain_ip":"%s"}\n' "$matches" "$server_ip" "$domain_ip"
}
