<?php

declare(strict_types=1);

require_once dirname(__DIR__, 2) . '/core/auth.php';
require_once dirname(__DIR__, 2) . '/core/csrf.php';
require_once dirname(__DIR__, 2) . '/core/validation.php';
require_once dirname(__DIR__, 2) . '/core/audit.php';

function user_module_boot(): void
{
    require_login();
    require_permission('manage_users');
}

function user_role_options(): array
{
    return db_fetch_all('SELECT id, name, description FROM roles ORDER BY name ASC');
}

function user_club_options(): array
{
    return db_fetch_all('SELECT id, name, short_name, status FROM clubs ORDER BY name ASC');
}

function get_user_by_id(int $userId): ?array
{
    return db_fetch_one(
        'SELECT u.*, r.name AS role_name, c.name AS club_name
         FROM users u
         INNER JOIN roles r ON r.id = u.role_id
         LEFT JOIN clubs c ON c.id = u.club_id
         WHERE u.id = :id
         LIMIT 1',
        ['id' => $userId]
    );
}

function find_user_or_abort(int $userId): array
{
    $user = get_user_by_id($userId);

    if ($user === null) {
        abort_request(404, 'User not found', 'The requested user record does not exist.');
    }

    return $user;
}

function active_super_admin_count(?int $excludeUserId = null): int
{
    $sql = 'SELECT COUNT(*)
            FROM users u
            INNER JOIN roles r ON r.id = u.role_id
            WHERE r.name = :role_name
              AND u.status = :status';
    $params = [
        'role_name' => 'Super Admin',
        'status' => 'active',
    ];

    if ($excludeUserId !== null) {
        $sql .= ' AND u.id <> :exclude_id';
        $params['exclude_id'] = $excludeUserId;
    }

    return (int) db_fetch_value($sql, $params, 0);
}

function role_name_by_id(int $roleId): ?string
{
    $role = db_fetch_one('SELECT name FROM roles WHERE id = :id LIMIT 1', ['id' => $roleId]);
    return $role['name'] ?? null;
}

function validate_user_payload(array $data, array &$errors, ?int $userId = null): array
{
    validate_required($data, [
        'full_name' => 'Full name',
        'email' => 'Email',
        'role_id' => 'Role',
        'status' => 'Status',
    ], $errors);
    validate_email_field($data, 'email', 'Email', $errors);
    validate_phone_field($data, 'phone', 'Phone', $errors);
    validate_in_array_field($data, 'status', ['active', 'inactive'], 'Status', $errors);

    $normalized = [
        'full_name' => trim((string) ($data['full_name'] ?? '')),
        'email' => strtolower(trim((string) ($data['email'] ?? ''))),
        'phone' => trim((string) ($data['phone'] ?? '')),
        'role_id' => (int) ($data['role_id'] ?? 0),
        'club_id' => ($data['club_id'] ?? '') === '' ? null : (int) $data['club_id'],
        'status' => (string) ($data['status'] ?? 'active'),
    ];

    if ($normalized['role_id'] <= 0 || role_name_by_id($normalized['role_id']) === null) {
        $errors['role_id'] = 'Selected role is invalid.';
    }

    if ($normalized['email'] !== '' && duplicate_exists('users', 'email', $normalized['email'], $userId)) {
        $errors['email'] = 'Email is already assigned to another user.';
    }

    $roleName = $normalized['role_id'] > 0 ? role_name_by_id($normalized['role_id']) : null;

    if (in_array($roleName, ['Club Admin', 'Coach'], true)) {
        if ($normalized['club_id'] === null || $normalized['club_id'] <= 0) {
            $errors['club_id'] = $roleName . ' users must be assigned to a club.';
        } else {
            $clubExists = db_fetch_one('SELECT id FROM clubs WHERE id = :id LIMIT 1', ['id' => $normalized['club_id']]);
            if ($clubExists === null) {
                $errors['club_id'] = 'Selected club is invalid.';
            }
        }
    } else {
        $normalized['club_id'] = null;
    }

    return $normalized;
}

function should_block_last_super_admin_change(array $existingUser, int $newRoleId, string $newStatus): bool
{
    if (($existingUser['role_name'] ?? '') !== 'Super Admin') {
        return false;
    }

    $nextRoleName = role_name_by_id($newRoleId) ?? '';
    $removesSuperAdminAccess = $nextRoleName !== 'Super Admin' || $newStatus !== 'active';

    return $removesSuperAdminAccess && active_super_admin_count((int) $existingUser['id']) === 0;
}

function user_badge_class(string $status): string
{
    return $status === 'active' ? 'badge-soft-success' : 'badge-soft-danger';
}
