#!/usr/bin/env bash
# Script: setup_bewpro_project.sh
# Descripción: Automatiza el proceso de creación de proyecto según 1-alta-proyecto.md
# Uso: ./setup_bewpro_project.sh --project lawfirm --domain lawfirm.bewpro.com --repo git@github.com:LACOMPANIADIGITAL/bewpro-lawfirm.git

set -euo pipefail

# Colores
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'

# Variables
PROJECT_NAME=""
DOMAIN=""
REPO_URL=""
BRANCH="cd-system"
CPANEL_PASSWORD=""
DB_PASSWORD=""

print_step() {
    echo -e "${BLUE}[PASO]${NC} $1"
}

print_success() {
    echo -e "${GREEN}✅${NC} $1"
}

print_error() {
    echo -e "${RED}❌${NC} $1"
}

print_info() {
    echo -e "${CYAN}ℹ️${NC} $1"
}

# Función para generar contraseña
gen_password() {
    openssl rand -base64 12 | tr -d '/+=' | cut -c1-14
}

# Función para verificar si usuario existe
user_exists() {
    whmapi1 listaccts searchtype=user search="$1" 2>/dev/null | grep -q "user.*$1"
}

# PASO 1: Crear cuenta cPanel
create_cpanel_account() {
    local username="$1"
    local domain="$2"
    local password="$3"

    print_step "1. Creando cuenta cPanel..."
    print_info "   Domain: $domain"
    print_info "   Username: $username"

    if user_exists "$username"; then
        print_error "Usuario $username ya existe"
        return 1
    fi

    local result
    result=$(whmapi1 createacct \
        domain="$domain" \
        username="$username" \
        password="$password" \
        plan="default" \
        contactemail="admin@bewpro.com" \
        quota=0 2>&1)

    if [ $? -eq 0 ] && user_exists "$username"; then
        print_success "Cuenta cPanel creada: $username"
        return 0
    else
        print_error "Error al crear cuenta cPanel"
        echo "$result" | grep -i "error\|message\|reason" | head -5
        return 1
    fi
}

# Función auxiliar para verificar si hay errores en la respuesta de uapi
check_uapi_error() {
    local result="$1"
    # Verificar si hay errores en la respuesta (incluso si status=0)
    # La API puede retornar status=0 pero con errores en el campo "errors"

    # Si hay "Error ID:" definitivamente hay error
    if echo "$result" | grep -qi "Error ID:"; then
        return 1  # Hay error
    fi

    # Verificar el campo "errors:" en la respuesta
    # Formato puede ser: errors: ~ (sin errores) o errors: [ "mensaje" ] (con errores)
    if echo "$result" | grep -qi "errors:"; then
        # Si errors no es "~" y tiene contenido, hay error
        if echo "$result" | grep -qi "errors:\s*\[" && ! echo "$result" | grep -qi "errors:\s*\[\s*\]"; then
            return 1  # Hay error (errors tiene contenido)
        fi
        # Si errors es "~" no hay error
        if echo "$result" | grep -qi "errors:\s*~"; then
            return 0  # No hay error
        fi
    fi

    return 0  # No hay error (por defecto)
}

# PASO 2: Crear base de datos (siguiendo nomenclatura: {username}_db, {username}_usr)
create_database() {
    local username="$1"
    local db_name="${username}_db"
    local db_user="${username}_usr"
    local db_pass="$2"

    print_step "2. Creando base de datos MySQL..."
    print_info "   Database: $db_name"
    print_info "   User: $db_user"

    # Crear base de datos
    print_info "   Creando base de datos..."
    local db_result
    db_result=$(uapi --user="$username" Mysql create_database name="$db_name" 2>&1)
    local db_exit_code=$?

    # Verificar resultado (tanto código como contenido)
    if [ $db_exit_code -ne 0 ] || ! check_uapi_error "$db_result"; then
        if echo "$db_result" | grep -qi "already exists"; then
            print_info "Base de datos $db_name ya existe, continuando..."
        else
            print_error "Error al crear base de datos"
            echo "Resultado completo:"
            echo "$db_result" | head -20
            return 1
        fi
    else
        print_success "Base de datos $db_name creada"
    fi

    # Esperar un momento para que cPanel procese
    sleep 1

    # Crear usuario
    print_info "   Creando usuario de BD..."
    local user_result
    user_result=$(uapi --user="$username" Mysql create_user name="$db_user" password="$db_pass" 2>&1)
    local user_exit_code=$?

    # Verificar resultado detalladamente
    if [ $user_exit_code -ne 0 ] || ! check_uapi_error "$user_result"; then
        if echo "$user_result" | grep -qi "already exists"; then
            print_info "Usuario $db_user ya existe, continuando..."
        else
            print_error "Error al crear usuario"
            echo "Resultado completo:"
            echo "$user_result" | head -20
            return 1
        fi
    else
        print_success "Usuario $db_user creado"
    fi

    # Verificar que el usuario realmente existe
    print_info "   Verificando que el usuario existe..."
    sleep 2
    local verify_users
    verify_users=$(uapi --user="$username" Mysql list_users 2>&1)

    # Verificar si el usuario aparece en la lista
    # La respuesta puede ser: data: [] (vacío) o data: [ { user: "nombre" } ]
    local user_found=false
    if echo "$verify_users" | grep -q "$db_user"; then
        user_found=true
    elif echo "$verify_users" | grep -A 20 "data:" | grep -q "$db_user"; then
        user_found=true
    fi

    if [ "$user_found" = true ]; then
        print_success "Usuario $db_user verificado en la lista"
    else
        print_error "Usuario $db_user NO aparece en la lista de usuarios"
        echo "Respuesta de list_users:"
        echo "$verify_users" | head -15
        echo ""
        print_info "Intentando crear usuario nuevamente con espera más larga..."
        sleep 3
        # Intentar crear de nuevo
        user_result=$(uapi --user="$username" Mysql create_user name="$db_user" password="$db_pass" 2>&1)
        if check_uapi_error "$user_result"; then
            print_success "Usuario creado en segundo intento"
            sleep 2
            # Verificar nuevamente
            verify_users=$(uapi --user="$username" Mysql list_users 2>&1)
            if echo "$verify_users" | grep -q "$db_user"; then
                print_success "Usuario $db_user verificado después del segundo intento"
            else
                print_error "Usuario creado pero aún no aparece en la lista"
                print_info "Esto puede ser normal - continuando con asignación de privilegios..."
            fi
        else
            print_error "No se pudo crear el usuario después de dos intentos"
            echo "Resultado:"
            echo "$user_result" | head -20
            return 1
        fi
    fi

    # Esperar un momento antes de asignar privilegios
    sleep 1

    # Asignar privilegios
    print_info "   Asignando privilegios ALL..."
    local priv_result
    priv_result=$(uapi --user="$username" Mysql set_privileges_on_database \
        user="$db_user" \
        database="$db_name" \
        privileges=ALL 2>&1)
    local priv_exit_code=$?

    # Verificar resultado (la API puede retornar status=0 con errores)
    if [ $priv_exit_code -ne 0 ] || ! check_uapi_error "$priv_result"; then
        print_error "Error al asignar privilegios"
        echo "Resultado completo:"
        echo "$priv_result" | head -20

        # Verificar estado de la base de datos
        print_info "   Verificando estado de la base de datos..."
        sleep 1
        local db_list
        db_list=$(uapi --user="$username" Mysql list_databases 2>&1)
        echo "$db_list" | grep -A 5 "$db_name" | head -10

        # Intentar asignar privilegios nuevamente
        print_info "   Reintentando asignar privilegios..."
        sleep 2
        priv_result=$(uapi --user="$username" Mysql set_privileges_on_database \
            user="$db_user" \
            database="$db_name" \
            privileges=ALL 2>&1)

        if check_uapi_error "$priv_result"; then
            print_success "Privilegios asignados en segundo intento"
        else
            print_error "No se pudieron asignar privilegios después de dos intentos"
            echo "$priv_result" | head -20
            return 1
        fi
    else
        print_success "Privilegios asignados (ALL)"
    fi

    # Verificación final: verificar que la BD tiene usuarios asociados
    print_info "   Verificación final..."
    sleep 1
    local db_info
    db_info=$(uapi --user="$username" Mysql list_databases 2>&1)

    if echo "$db_info" | grep -A 5 "$db_name" | grep -q "$db_user"; then
        print_success "Usuario $db_user verificado en base de datos $db_name"
    else
        print_info "Verificación parcial (usuario puede estar asociado)"
    fi

    echo ""
    print_info "Credenciales BD:"
    echo "   Database: $db_name"
    echo "   User: $db_user"
    echo "   Password: $db_pass"
    return 0
}

# PASO 3: Configurar claves SSH (exactamente como en 1-alta-proyecto.md)
setup_ssh_keys() {
    local username="$1"
    local home_dir="/home/$username"
    local ssh_dir="$home_dir/.ssh"
    local root_ssh_dir="/root/.ssh"

    print_step "3. Configurando claves SSH..."

    mkdir -p "$ssh_dir"

    if [ -f "$root_ssh_dir/id_rsa" ]; then
        cp "$root_ssh_dir/id_rsa" "$ssh_dir/id_rsa"
        cp "$root_ssh_dir/id_rsa.pub" "$ssh_dir/id_rsa.pub"
        print_success "Copiada clave RSA"
    fi

    if [ -f "$root_ssh_dir/id_ed25519" ]; then
        cp "$root_ssh_dir/id_ed25519" "$ssh_dir/id_ed25519"
        cp "$root_ssh_dir/id_ed25519.pub" "$ssh_dir/id_ed25519.pub"
        print_success "Copiada clave Ed25519"
    fi

    cat "$ssh_dir"/*.pub > "$ssh_dir/authorized_keys" 2>/dev/null || true

    chown -R "$username:$username" "$ssh_dir"
    chmod 700 "$ssh_dir"
    chmod 600 "$ssh_dir"/*
    chmod 644 "$ssh_dir"/*.pub 2>/dev/null || true
    chmod 600 "$ssh_dir/authorized_keys"

    print_success "Claves SSH configuradas para $username"
}

# PASO 4: Clonar repositorio (en public_html/git-files/{repo_name})
clone_repository() {
    local username="$1"
    local repo_url="$2"
    local branch="$3"
    local home_dir="/home/$username"
    local public_html="$home_dir/public_html"
    local git_files_dir="$public_html/git-files"

    # Extraer nombre del repo
    local repo_name
    if [[ "$repo_url" =~ github.com[:/]([^/]+)/([^/]+)\.git ]]; then
        repo_name="${BASH_REMATCH[2]}"
    else
        repo_name=$(basename "$repo_url" .git)
    fi

    local repo_path="$git_files_dir/$repo_name"

    print_step "4. Clonando repositorio..."
    print_info "   URL: $repo_url"
    print_info "   Branch: $branch"
    print_info "   Path: $repo_path"

    # Crear directorio git-files si no existe
    sudo -u "$username" mkdir -p "$git_files_dir"

    # Clonar repositorio
    sudo -u "$username" bash -c "
        cd \"$git_files_dir\" || exit 1
        if [ -d \"$repo_name/.git\" ]; then
            echo '⚠️  Repositorio ya existe, saltando clonación'
        else
            GIT_SSH_COMMAND='ssh -o StrictHostKeyChecking=no' git clone \"$repo_url\" \"$repo_name\" || exit 1
        fi
    "

    if [ $? -ne 0 ]; then
        print_error "Error al clonar repositorio"
        return 1
    fi

    # Cambiar a la rama correcta
    sudo -u "$username" bash -c "
        cd \"$repo_path\" || exit 1
        if git rev-parse --verify \"$branch\" >/dev/null 2>&1; then
            git checkout \"$branch\"
        else
            git fetch --all
            git checkout -b \"$branch\" \"origin/$branch\" || true
        fi
    "

    print_success "Repositorio clonado en $repo_path"
    print_info "   Rama activa: $branch"
}

# Guardar credenciales
save_credentials() {
    local username="$1"
    local cpanel_pass="$2"
    local db_name="${username}_db"
    local db_user="${username}_usr"
    local db_pass="$3"

    local cred_file="/root/credenciales"

    {
        echo "═══════════════════════════════════════════════════════════"
        echo "Proyecto: $username"
        echo "Fecha: $(date '+%Y-%m-%d %H:%M:%S')"
        echo ""
        echo "Cuenta cPanel:"
        echo "   Username: $username"
        echo "   Password: $cpanel_pass"
        echo ""
        echo "Base de datos:"
        echo "   Database: $db_name"
        echo "   User: $db_user"
        echo "   Password: $db_pass"
        echo "═══════════════════════════════════════════════════════════"
        echo ""
    } >> "$cred_file"

    print_success "Credenciales guardadas en $cred_file"
}

# Función principal
main() {
    # Verificar que se ejecuta como root
    if [ "$EUID" -ne 0 ]; then
        print_error "Este script debe ejecutarse como root"
        exit 1
    fi

    # Parsear argumentos
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --project)
                PROJECT_NAME="$2"
                shift 2
                ;;
            --domain)
                DOMAIN="$2"
                shift 2
                ;;
            --repo)
                REPO_URL="$2"
                shift 2
                ;;
            --branch)
                BRANCH="$2"
                shift 2
                ;;
            --cpanel-password)
                CPANEL_PASSWORD="$2"
                shift 2
                ;;
            --db-password)
                DB_PASSWORD="$2"
                shift 2
                ;;
            --help)
                echo "Uso: $0 --project NOMBRE --domain DOMINIO --repo URL_REPO [opciones]"
                echo ""
                echo "Opciones:"
                echo "  --project NOMBRE        Nombre del proyecto (usuario cPanel)"
                echo "  --domain DOMINIO       Dominio completo (ej: lawfirm.bewpro.com)"
                echo "  --repo URL             URL del repositorio Git"
                echo "  --branch RAMA          Rama a clonar (default: cd-system)"
                echo "  --cpanel-password PASS Contraseña cPanel (si no se proporciona, se genera)"
                echo "  --db-password PASS     Contraseña BD (si no se proporciona, se genera)"
                exit 0
                ;;
            *)
                print_error "Opción desconocida: $1"
                exit 1
                ;;
        esac
    done

    # Validar parámetros requeridos
    if [ -z "$PROJECT_NAME" ] || [ -z "$DOMAIN" ] || [ -z "$REPO_URL" ]; then
        print_error "Faltan parámetros requeridos"
        echo "Uso: $0 --project NOMBRE --domain DOMINIO --repo URL_REPO"
        echo "Ejecuta: $0 --help para más información"
        exit 1
    fi

    # Generar contraseñas si no se proporcionaron
    if [ -z "$CPANEL_PASSWORD" ]; then
        CPANEL_PASSWORD=$(gen_password)
        print_info "Contraseña cPanel generada automáticamente"
    fi

    if [ -z "$DB_PASSWORD" ]; then
        DB_PASSWORD=$(gen_password)
        print_info "Contraseña BD generada automáticamente"
    fi

    echo ""
    echo "═══════════════════════════════════════════════════════════"
    echo "  Configuración de Proyecto: $PROJECT_NAME"
    echo "═══════════════════════════════════════════════════════════"
    echo ""
    echo "Domain:        $DOMAIN"
    echo "Username:     $PROJECT_NAME"
    echo "Repository:   $REPO_URL"
    echo "Branch:       $BRANCH"
    echo ""
    read -p "¿Continuar con la creación? (y/N): " -n 1 -r
    echo ""
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
        print_info "Operación cancelada"
        exit 0
    fi
    echo ""

    # Ejecutar pasos
    create_cpanel_account "$PROJECT_NAME" "$DOMAIN" "$CPANEL_PASSWORD" || exit 1
    echo ""

    create_database "$PROJECT_NAME" "$DB_PASSWORD" || exit 1
    echo ""

    setup_ssh_keys "$PROJECT_NAME" || exit 1
    echo ""

    clone_repository "$PROJECT_NAME" "$REPO_URL" "$BRANCH" || exit 1
    echo ""

    save_credentials "$PROJECT_NAME" "$CPANEL_PASSWORD" "$DB_PASSWORD"
    echo ""

    echo "═══════════════════════════════════════════════════════════"
    print_success "Proceso completado exitosamente"
    echo "═══════════════════════════════════════════════════════════"
    echo ""
    print_info "Ver credenciales: cat /root/credenciales"
    print_info "Acceder al proyecto: cd /home/$PROJECT_NAME/public_html/git-files/$(basename "$REPO_URL" .git)"
}

main "$@"
