<?php

namespace App\Models\Scopes;

use App\Services\CurrentContext;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Support\Facades\Auth;

/**
 * Branch scoping for models with two branch columns (e.g. StockTransfer's
 * from_branch_id/to_branch_id), where a single {@see BranchScope} column
 * can't express "visible if the user can access either endpoint." Otherwise
 * mirrors BranchScope's decision tree exactly.
 *
 * Bypass when needed: `Model::withoutGlobalScope(DualBranchScope::class)`.
 */
class DualBranchScope implements Scope
{
    public function __construct(
        private readonly string $fromColumn = 'from_branch_id',
        private readonly string $toColumn = 'to_branch_id',
    ) {}

    public function apply(Builder $builder, Model $model): void
    {
        if (! Auth::check()) {
            return;
        }

        $context = app(CurrentContext::class);
        $table = $model->getTable();
        $from = $table.'.'.$this->fromColumn;
        $to = $table.'.'.$this->toColumn;

        if ($context->isAllBranches()) {
            $accessible = $context->accessibleBranchIds();
            if ($accessible !== null) {
                $builder->where(fn ($q) => $q->whereIn($from, $accessible)->orWhereIn($to, $accessible));
            }

            return;
        }

        if ($context->hasUnrestrictedBranchAccess() && ! $context->hasExplicitBranch()) {
            return;
        }

        $branchId = $context->branchId();
        if ($branchId === null) {
            $builder->whereRaw('1 = 0');

            return;
        }

        $builder->where(fn ($q) => $q->where($from, $branchId)->orWhere($to, $branchId));
    }
}
