<?php

namespace App\Services;

use App\Models\User;
use Closure;

class BranchContext
{
    private bool $systemWide = false;
    private ?array $branchIds = null;

    public function __construct(private BranchAccessService $branchAccess)
    {
    }

    public function isSystemWide(): bool
    {
        return $this->systemWide;
    }

    public function branchIds(): ?array
    {
        return $this->branchIds;
    }

    public function forUser(User $user, Closure $callback): mixed
    {
        return $this->branchAccess->isSystemWide($user)
            ? $this->systemWide($callback)
            : $this->forBranches($this->branchAccess->accessibleBranchIds($user), $callback);
    }

    public function forBranch(int $branchId, Closure $callback): mixed
    {
        return $this->forBranches([$branchId], $callback);
    }

    public function forBranches(array $branchIds, Closure $callback): mixed
    {
        $branchIds = collect($branchIds)
            ->map(fn ($id) => (int) $id)
            ->filter(fn ($id) => $id > 0)
            ->unique()
            ->values()
            ->all();

        return $this->run(false, $branchIds, $callback);
    }

    public function systemWide(Closure $callback): mixed
    {
        return $this->run(true, null, $callback);
    }

    private function run(bool $systemWide, ?array $branchIds, Closure $callback): mixed
    {
        $previousSystemWide = $this->systemWide;
        $previousBranchIds = $this->branchIds;

        $this->systemWide = $systemWide;
        $this->branchIds = $branchIds;

        try {
            return $callback();
        } finally {
            $this->systemWide = $previousSystemWide;
            $this->branchIds = $previousBranchIds;
        }
    }
}
