<?php
// FILE: /digitalpremium/actions/usuario_controlador.php
declare(strict_types=1);

if (session_status() === PHP_SESSION_NONE) {
    session_start();
}

// Requiere sesión activa
if (!isset($_SESSION['id_usuario'])) {
    header("Location: /digitalpremium/login.php");
    exit();
}

require_once '../config/db.php';
require_once '../includes/audit_helper.php';

/**
 * Redirige con mensaje y corta ejecución.
 */
function redirect_with_message(string $page, string $message, string $type = 'danger'): void {
    header("Location: {$page}?mensaje=" . urlencode($message) . "&tipo={$type}");
    exit();
}

/**
 * Valida CSRF con hash_equals (best effort).
 */
function validar_csrf(): void {
    $token_form = $_POST['csrf_token'] ?? '';
    $token_sess = $_SESSION['csrf_token'] ?? '';
    if ($token_form === '' || $token_sess === '' || !hash_equals($token_sess, $token_form)) {
        redirect_with_message('/digitalpremium/pages/configuracion.php', 'La sesión caducó. Vuelve a intentar.', 'danger');
    }
}

// La función auditar ahora está en el helper de auditoría

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    redirect_with_message('/digitalpremium/pages/configuracion.php', 'Acceso denegado.');
}

$accion = $_POST['accion'] ?? '';

switch ($accion) {

    case 'cambiar_contrasena':
        validar_csrf();

        $id_usuario  = (int)$_SESSION['id_usuario'];
        $rol_usuario = (string)($_SESSION['rol'] ?? 'usuario');

        $current_password      = (string)($_POST['current_password'] ?? '');
        $new_password          = (string)($_POST['new_password'] ?? '');
        $confirm_new_password  = (string)($_POST['confirm_new_password'] ?? '');

        // Validaciones básicas
        if ($current_password === '' || $new_password === '' || $confirm_new_password === '') {
            redirect_with_message('/digitalpremium/pages/configuracion.php', 'Todos los campos de contraseña son obligatorios.');
        }
        if ($new_password !== $confirm_new_password) {
            redirect_with_message('/digitalpremium/pages/configuracion.php', 'La nueva contraseña y la confirmación no coinciden.');
        }
        if (strlen($new_password) < 8) {
            redirect_with_message('/digitalpremium/pages/configuracion.php', 'La nueva contraseña debe tener al menos 8 caracteres.');
        }
        // (Opcional) Reglas extra de complejidad:
        // if (!preg_match('/[A-Z]/', $new_password) || !preg_match('/[a-z]/', $new_password) || !preg_match('/\d/', $new_password)) {
        //     redirect_with_message('/digitalpremium/pages/configuracion.php', 'La nueva contraseña debe incluir mayúsculas, minúsculas y números.');
        // }

        try {
            $pdo->beginTransaction();

            // Obtener hash actual
            $stmt = $pdo->prepare("SELECT password FROM usuarios WHERE id_usuario = ? LIMIT 1");
            $stmt->execute([$id_usuario]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$row) {
                // Auditar intento fallido (usuario no existe)
                auditar($pdo, $id_usuario, $rol_usuario, 'cambiar_contrasena', [
                    'resultado' => 'fallo',
                    'motivo'    => 'usuario_no_encontrado'
                ]);
                $pdo->commit(); // cerramos transacción igualmente
                redirect_with_message('/digitalpremium/pages/configuracion.php', 'Error: Usuario no encontrado.');
            }

            $hash_actual = (string)$row['password'];

            // Verificar contraseña actual
            if (!password_verify($current_password, $hash_actual)) {
                auditar($pdo, $id_usuario, $rol_usuario, 'cambiar_contrasena', [
                    'resultado' => 'fallo',
                    'motivo'    => 'password_actual_incorrecta'
                ]);
                $pdo->commit();
                redirect_with_message('/digitalpremium/pages/configuracion.php', 'La contraseña actual es incorrecta.');
            }

            // Evitar misma contraseña
            if (password_verify($new_password, $hash_actual)) {
                auditar($pdo, $id_usuario, $rol_usuario, 'cambiar_contrasena', [
                    'resultado' => 'fallo',
                    'motivo'    => 'nueva_igual_a_actual'
                ]);
                $pdo->commit();
                redirect_with_message('/digitalpremium/pages/configuracion.php', 'La nueva contraseña no puede ser igual a la actual.', 'info');
            }

            // Hashear nueva contraseña
            $hash_nuevo = password_hash($new_password, PASSWORD_DEFAULT);

            // Actualizar
            $upd = $pdo->prepare("UPDATE usuarios SET password = ? WHERE id_usuario = ?");
            $upd->execute([$hash_nuevo, $id_usuario]);

            // Auditoría de éxito
            auditar($pdo, $id_usuario, $rol_usuario, 'cambiar_contrasena', [
                'resultado' => 'exito'
            ]);

            $pdo->commit();

            // Seguridad de sesión: regenerar ID y rotar CSRF
            session_regenerate_id(true);
            $_SESSION['csrf_token'] = bin2hex(random_bytes(32));

            redirect_with_message('/digitalpremium/pages/configuracion.php', 'Contraseña actualizada exitosamente.', 'success');

        } catch (Throwable $e) {
            if ($pdo->inTransaction()) $pdo->rollBack();
            error_log("Error cambiar_contrasena (usuario {$id_usuario}): " . $e->getMessage());
            redirect_with_message('/digitalpremium/pages/configuracion.php', 'Ocurrió un error al intentar cambiar la contraseña. Intenta más tarde.');
        }

        break;

    default:
        redirect_with_message('/digitalpremium/pages/configuracion.php', 'Acción no válida.');
}
