<?php
/**
 * avatar_helpers.php
 * Contiene funciones centralizadas para gestionar la subida, validación
 * y eliminación de avatares de perfil.
 */

// --- Constantes de Configuración ---

/**
 * Ruta a la carpeta de avatares (desde la raíz del script).
 * ASEGÚRATE de que esta carpeta exista y tenga permisos de escritura (ej. 755 o 777).
 */
define('AVATAR_UPLOAD_PATH', __DIR__ . '/avatar/');

/**
 * Ruta relativa que se guardará en la BBDD.
 */
define('AVATAR_DB_PATH', 'avatar/');

/**
 * Tamaño máximo del archivo en bytes (1 MB).
 */
define('MAX_AVATAR_SIZE', 1048576); // 1 * 1024 * 1024

/**
 * Tipos de imagen permitidos.
 */
const ALLOWED_AVATAR_TYPES = [
    'image/jpeg' => 'jpg',
    'image/png' => 'png',
    'image/gif' => 'gif'
];


/**
 * Valida un archivo de avatar subido.
 *
 * @param array $file El array $_FILES['avatar']
 * @return string|true Retorna true si es válido, o un string con el mensaje de error.
 */
function validateAvatarFile($file) {
    if (!isset($file) || $file['error'] !== UPLOAD_ERR_OK) {
        return 'Error en la pujada del fitxer.';
    }

    if ($file['size'] > MAX_AVATAR_SIZE) {
        return 'El fitxer és massa gran (màx. 1 MB).'; // (c) Validación 1MB
    }

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime_type = finfo_file($finfo, $file['tmp_name']);
    finfo_close($finfo);

    if (!array_key_exists($mime_type, ALLOWED_AVATAR_TYPES)) {
        return 'Format de fitxer no permès (només JPG, PNG, GIF).';
    }

    // Comprobación adicional de que es una imagen real
    if (getimagesize($file['tmp_name']) === false) {
        return 'El fitxer no sembla una imatge vàlida.';
    }

    return true;
}

/**
 * Elimina un archivo de avatar del disco de forma segura.
 *
 * @param string $avatar_db_path La ruta guardada en la BBDD (ej. "avatar/user_1.jpg")
 * @return bool True si se borró o no existía, false si falló el borrado.
 */
function deleteAvatarFile($avatar_db_path) {
    if (empty($avatar_db_path)) {
        return true; // No hay nada que borrar
    }

    // Seguridad: Asegurarse de que el path empieza con AVATAR_DB_PATH
    if (strpos($avatar_db_path, AVATAR_DB_PATH) !== 0) {
        error_log("Intent d'esborrat d'avatar fora de la carpeta: " . $avatar_db_path);
        return false; // No intentar borrar archivos fuera del directorio
    }

    // Construir la ruta completa del disco
    $file_path_on_disk = AVATAR_UPLOAD_PATH . basename($avatar_db_path);

    if (file_exists($file_path_on_disk) && is_writable($file_path_on_disk)) {
        if (@unlink($file_path_on_disk)) {
            return true; // Borrado con éxito
        } else {
            error_log("No s'ha pogut esborrar l'avatar antic: " . $file_path_on_disk);
            return false; // Fallo al borrar
        }
    }

    return true; // El archivo no existía, así que "éxito"
}


/**
 * Gestiona la actualización completa del perfil, incluyendo el avatar.
 * Esta función actualiza la BBDD y el disco.
 *
 * @param PDO $db Conexión a la BBDD.
 * @param int $user_id ID del usuario a actualizar.
 * @param array $form_data Los datos de $_POST.
 * @param array $file_data Los datos de $_FILES.
 * @param string $user_role Rol del usuario ('paciente' o 'fisio'/'superadmin').
 * @return array Array con el resultado de la operación.
 */
function handleAvatarUpload(PDO $db, $user_id, $form_data, $file_data, $user_role) {

    // 1. Sanitizar datos de texto
    $nombre = trim($form_data['nombre'] ?? '');
    $apellido = trim($form_data['apellido'] ?? '');
    $email = trim($form_data['email'] ?? '');
    $telefono = trim($form_data['telefono'] ?? '');

    // (Lógica de validación de texto copiada de dashboard.php)
    if (empty($nombre) || empty($apellido) || empty($email)) {
        throw new Exception("Nom, cognoms i email són obligatoris.");
    }
    if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        throw new Exception("El format de l'email no és vàlid.");
    }

    // Comprobar email duplicado
    $stmt_check_email = $db->prepare("SELECT id FROM cuentas WHERE email = ? AND id != ?");
    $stmt_check_email->execute([$email, $user_id]);
    if ($stmt_check_email->fetch()) {
        throw new Exception("L'email ja està en ús per un altre usuari.");
    }

    // 2. Obtener el avatar actual
    $stmt_current = $db->prepare("SELECT avatar FROM cuentas WHERE id = ?");
    $stmt_current->execute([$user_id]);
    $current_avatar_path = $stmt_current->fetchColumn();

    $avatar_sql_part = ""; // Parte de la query SQL para el avatar
    $sql_params = [];      // Parámetros para la query
    $new_avatar_url = $current_avatar_path; // Por defecto, mantiene el actual

    // 3. Gestionar borrado o subida
    $wants_to_delete = isset($form_data['delete_avatar']) && $form_data['delete_avatar'] == '1';
    $has_new_file = isset($file_data['avatar']) && $file_data['avatar']['error'] === UPLOAD_ERR_OK;

    if ($wants_to_delete) {
        // (d) Eliminar la foto de la carpeta
        deleteAvatarFile($current_avatar_path);
        $avatar_sql_part = ", avatar = NULL";
        $new_avatar_url = ''; // Vacío para el frontend

    } elseif ($has_new_file) {
        // (c) Validar el nuevo archivo
        $file = $file_data['avatar'];
        $validation = validateAvatarFile($file);

        if ($validation !== true) {
            throw new Exception($validation); // Lanza error si no es válido
        }

        // (d) Eliminar el avatar antiguo ANTES de subir el nuevo
        deleteAvatarFile($current_avatar_path);

        // (a) Mover el nuevo archivo a la carpeta 'avatar/'
        $extension = ALLOWED_AVATAR_TYPES[finfo_file(finfo_open(FILEINFO_MIME_TYPE), $file['tmp_name'])];
        $new_filename = "user_{$user_id}_" . time() . "." . $extension;
        $new_disk_path = AVATAR_UPLOAD_PATH . $new_filename;

        if (!move_uploaded_file($file['tmp_name'], $new_disk_path)) {
            throw new Exception("Error al moure el fitxer pujat al servidor.");
        }

        // (b) Preparar para guardar en la BBDD
        $new_avatar_url = AVATAR_DB_PATH . $new_filename; // ej: "avatar/user_1_12345.jpg"
        $avatar_sql_part = ", avatar = ?";
        $sql_params[] = $new_avatar_url;
    }
    // Si no se borra ni se sube, $avatar_sql_part es "" y se mantiene el avatar actual.

    // 4. Construir y ejecutar la query de actualización
    $sql_params_base = [
        $nombre,
        $apellido,
        $email,
        $telefono,
    ];

    // Lógica para fisio/admin (tiene campo extra)
    if ($user_role !== 'paciente') {
        $filtro = isset($form_data['filtro_personal_defecto']) && $form_data['filtro_personal_defecto'] == 1 ? 1 : 0;
        $sql_part_extra_fisio = ", filtro_personal_defecto = ?";
        $sql_params_base[] = $filtro;
    } else {
        $sql_part_extra_fisio = "";
    }

    $sql = "UPDATE cuentas
            SET nombre = ?, apellido = ?, email = ?, telefono = ?
            {$sql_part_extra_fisio}
            {$avatar_sql_part}
            WHERE id = ?";

    $sql_params = array_merge($sql_params_base, $sql_params, [$user_id]);

    $stmt_update = $db->prepare($sql);
    $stmt_update->execute($sql_params);

    // 5. Actualizar la sesión
    $_SESSION['user_nombre'] = $nombre;
    $_SESSION['user_apellido'] = $apellido; // Actualizar apellido en sesión
    $_SESSION['user_avatar'] = $new_avatar_url; // Actualizar avatar en sesión

    // 6. Devolver respuesta para JS (f)
    return [
        'status' => 'success',
        'message' => 'Dades actualitzades correctament.',
        'newName' => $nombre, // (f) Solo el nombre para el saludo
        'newFullName' => $nombre . ' ' . $apellido, // (f) Nombre completo por si se necesita
        'newAvatarUrl' => $new_avatar_url // (f) URL del nuevo avatar para actualización instantánea
    ];
}
