<?php
require_once __DIR__ . '/../config/user_functions.php';

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

/**
 * Carica tutti gli utenti dal database MySQL come array di:
 * [
 *   'username'    => string,
 *   'password'    => '',          // vuoto (non leggiamo l'hash)
 *   'name'        => full_name,
 *   'role'        => role,
 *   'active'      => bool,
 *   'permissions' => string[]
 * ]
 */
function get_users() {
    global $conn;

    $sql = "SELECT u.id, u.username, u.full_name, u.role, u.is_active,
                   GROUP_CONCAT(up.permission) AS perms
            FROM users u
            LEFT JOIN user_permissions up ON up.user_id = u.id
            GROUP BY u.id, u.username, u.full_name, u.role, u.is_active
            ORDER BY u.username ASC";

    $result = $conn->query($sql);
    if (!$result) {
        error_log('get_users query error: ' . $conn->error);
        return [];
    }

    $users = [];
    while ($row = $result->fetch_assoc()) {
        $perms = [];
        if (!empty($row['perms'])) {
            $perms = array_values(array_filter(array_map('trim', explode(',', $row['perms']))));
        }

        $users[] = [
            'id'          => (int)$row['id'],
            'username'    => $row['username'],
            'password'    => '', // non esponiamo la password
            'name'        => $row['full_name'],
            'role'        => $row['role'],
            'active'      => (bool)$row['is_active'],
            'permissions' => $perms,
        ];
    }

    return $users;
}

/**
 * Salva l'elenco completo utenti nel DB, sincronizzando:
 * - tabella users
 * - tabella user_permissions
 *
 * Accetta sia un array indicizzato che una mappa username => utente.
 */
function save_users(array $users) {
    global $conn;

    // normalizza a lista
    $users = array_values($users);

    // mappa utenti esistenti: username => [id, username]
    $existing = [];
    $res = $conn->query("SELECT id, username FROM users");
    if ($res) {
        while ($row = $res->fetch_assoc()) {
            $existing[$row['username']] = (int)$row['id'];
        }
    }

    // prepariamo statement per update e insert
    $updateStmt = $conn->prepare("UPDATE users SET full_name = ?, role = ?, is_active = ?, updated_at = NOW() WHERE id = ?");
    $insertStmt = $conn->prepare("INSERT INTO users (username, password_hash, full_name, role, is_active, created_at, updated_at)
                                  VALUES (?, ?, ?, ?, ?, NOW(), NOW())");
    $updatePwdStmt = $conn->prepare("UPDATE users SET password_hash = ? WHERE id = ?");

    // set desiderato di username
    $desiredUsernames = [];

    foreach ($users as $user) {
        $username = $user['username'] ?? '';
        if ($username === '') continue;

        $desiredUsernames[] = $username;

        $name   = $user['name'] ?? '';
        $role   = $user['role'] ?? 'viewer';
        $active = !empty($user['active']) ? 1 : 0;
        $perms  = isset($user['permissions']) && is_array($user['permissions']) ? $user['permissions'] : [];

        // esiste già?
        if (isset($existing[$username])) {
            $id = $existing[$username];

            // update base
            if ($updateStmt) {
                $updateStmt->bind_param("ssii", $name, $role, $active, $id);
                $updateStmt->execute();
            }

            // se password in chiaro presente, aggiorna l'hash
            if (!empty($user['password']) && $updatePwdStmt) {
                $hash = password_hash($user['password'], PASSWORD_DEFAULT);
                $updatePwdStmt->bind_param("si", $hash, $id);
                $updatePwdStmt->execute();
            }
        } else {
            // nuovo utente
            $pwdPlain = $user['password'] ?? '';
            $hash = $pwdPlain !== '' ? password_hash($pwdPlain, PASSWORD_DEFAULT) : password_hash(bin2hex(random_bytes(8)), PASSWORD_DEFAULT);

            if ($insertStmt) {
                $insertStmt->bind_param("ssssi", $username, $hash, $name, $role, $active);
                $insertStmt->execute();
                $id = $conn->insert_id;
                $existing[$username] = $id;
            } else {
                continue;
            }
        }

        $id = $existing[$username];

        // sincronizza i permessi per questo utente
        $delPerm = $conn->prepare("DELETE FROM user_permissions WHERE user_id = ?");
        if ($delPerm) {
            $delPerm->bind_param("i", $id);
            $delPerm->execute();
        }

        if (!empty($perms)) {
            $insPerm = $conn->prepare("INSERT INTO user_permissions (user_id, permission) VALUES (?, ?)");
            if ($insPerm) {
                foreach ($perms as $perm) {
                    $perm = trim($perm);
                    if ($perm === '') continue;
                    $insPerm->bind_param("is", $id, $perm);
                    $insPerm->execute();
                }
            }
        }
    }

    // elimina utenti che non sono più presenti nella lista (solo se vogliamo sync totale)
    if (!empty($desiredUsernames)) {
        // costruisci elenco per la clausola NOT IN
        $placeholders = implode(',', array_fill(0, count($desiredUsernames), '?'));
        $types = str_repeat('s', count($desiredUsernames));

        $sqlDelUsers = "SELECT id, username FROM users WHERE username NOT IN ($placeholders)";
        $stmtDelUsers = $conn->prepare($sqlDelUsers);
        if ($stmtDelUsers) {
            $stmtDelUsers->bind_param($types, ...$desiredUsernames);
            $stmtDelUsers->execute();
            $resDel = $stmtDelUsers->get_result();
            $toDeleteIds = [];
            while ($row = $resDel->fetch_assoc()) {
                $toDeleteIds[] = (int)$row['id'];
            }
            $stmtDelUsers->close();

            if (!empty($toDeleteIds)) {
                // elimina permessi collegati
                $inIds = implode(',', array_fill(0, count($toDeleteIds), '?'));
                $typesIds = str_repeat('i', count($toDeleteIds));

                $stmtDelPerm = $conn->prepare("DELETE FROM user_permissions WHERE user_id IN ($inIds)");
                if ($stmtDelPerm) {
                    $stmtDelPerm->bind_param($typesIds, ...$toDeleteIds);
                    $stmtDelPerm->execute();
                    $stmtDelPerm->close();
                }

                $stmtDelUsr = $conn->prepare("DELETE FROM users WHERE id IN ($inIds)");
                if ($stmtDelUsr) {
                    $stmtDelUsr->bind_param($typesIds, ...$toDeleteIds);
                    $stmtDelUsr->execute();
                    $stmtDelUsr->close();
                }
            }
        }
    }
}

/**
 * Restituisce singolo utente dal DB in formato array users.php-style.
 */
function get_user($username) {
    global $conn;

    $username = trim($username);
    if ($username === '') return null;

    $sql = "SELECT u.id, u.username, u.full_name, u.role, u.is_active,
                   GROUP_CONCAT(up.permission) AS perms
            FROM users u
            LEFT JOIN user_permissions up ON up.user_id = u.id
            WHERE u.username = ?
            GROUP BY u.id, u.username, u.full_name, u.role, u.is_active
            LIMIT 1";

    $stmt = $conn->prepare($sql);
    if (!$stmt) return null;
    $stmt->bind_param("s", $username);
    $stmt->execute();
    $res = $stmt->get_result();
    $row = $res->fetch_assoc();
    $stmt->close();

    if (!$row) return null;

    $perms = [];
    if (!empty($row['perms'])) {
        $perms = array_values(array_filter(array_map('trim', explode(',', $row['perms']))));
    }

    return [
        'id'          => (int)$row['id'],
        'username'    => $row['username'],
        'password'    => '',
        'name'        => $row['full_name'],
        'role'        => $row['role'],
        'active'      => (bool)$row['is_active'],
        'permissions' => $perms,
    ];
}

/**
 * Elenco permessi disponibili nel sistema.
 */
function available_permissions() {
    return [
        'dashboard_view'   => 'Dashboard',
        'dashboard_kpi'    => 'Dashboard KPI',
        'orders'           => 'Gestione ordini',
        'orders_view'      => 'Visualizza ordini',
        'production_view'  => 'Produzione',
        'bins_view'        => 'Bins',
        'ibc_view'         => 'IBC',
        'ibc_tables'       => 'Tabelle IBC',
        'ibc_tables_view'  => 'Tabelle IBC - view',
        'ibc_tables_edit'  => 'Tabelle IBC - edit',
        'ibc_tables_delete'=> 'Tabelle IBC - delete',
        'fullbins_edit'    => 'Full bins edit',
        'settings'         => 'Impostazioni',
        'settings_manage'  => 'Gestione impostazioni',
        'users_manage'     => 'Gestione utenti',
    ];
}

// NOTA: la funzione user_has_permission NON viene ridefinita qui.
// Viene usata quella di user_functions.php (DB-based) tramite alias.
