<?php

namespace App\Livewire\Users\Concerns;

use App\Models\User;
use Illuminate\Database\Eloquent\Builder;

/**
 * Which staff accounts the active branch is allowed to see.
 *
 * `users` deliberately carries no BranchScope and must not grow one: the
 * branch is resolved *from* the user (BranchContext::resolveForUser reads
 * role_user and preferred_branch_id), so scoping the table the resolver reads
 * would be circular and would take authentication down with it.
 *
 * Branch membership is real all the same — it lives on the `role_user` pivot —
 * so the predicate has to be written out by hand here. Writing it once, in one
 * place, is the point: a rule each screen re-remembers is a rule some screen
 * forgets, which is exactly what rule 19 exists to stop.
 *
 * Visible from branch B:
 *   - anyone holding a role assignment pinned to B, and
 *   - anyone with no pinned assignment anywhere — academy-wide staff, and the
 *     accounts on older tenants whose pivot branch was never filled in.
 *     Hard-filtering those would empty the staff list on most installs rather
 *     than tighten it.
 *
 * Pinned to another branch and nowhere else: not visible. That is the boundary.
 *
 * The component using this trait must also use UsesBranchScope — this trait
 * calls getActiveBranchId() but does not pull the trait in itself, so that a
 * component using both does not end up with the same method arriving twice.
 */
trait FiltersUsersByBranch
{
    /**
     * The user query every screen in this namespace should start from.
     */
    protected function branchUsers(): Builder
    {
        return $this->scopeUsersToBranch(User::query());
    }

    protected function scopeUsersToBranch(Builder $query): Builder
    {
        $branchId = $this->getActiveBranchId();

        // Null is "all branches" — a deliberate, permission-gated mode, not a
        // missing value. Filtering here would break the one view that is meant
        // to be cross-branch.
        if ($branchId === null) {
            return $query;
        }

        return $query->where(function (Builder $outer) use ($branchId) {
            $outer->whereHas(
                'roles',
                fn ($r) => $r->where('role_user.branch_id', $branchId)
            )->orWhereDoesntHave(
                'roles',
                fn ($r) => $r->whereNotNull('role_user.branch_id')
            );
        });
    }
}
