<?php

namespace App\Domain\Shared\Traits;

use App\Domain\Shared\Context\BranchScopeState;
use App\Domain\Shared\Scopes\BranchScopeThrough;
use Illuminate\Database\Eloquent\Builder;

/**
 * A row whose branch is its parent's — enforced without a column of its own.
 *
 * For line items and pivots: invoice items, POS lines, payslip items,
 * evaluation scores, installments, purchase-order lines. They are never listed
 * on their own screen, but they are aggregated by reports and dashboards, and
 * an unscoped SUM over invoice_items is exactly the kind of cross-branch total
 * that reads as a data bug rather than a leak.
 *
 * Declare the owning relation on the model:
 *
 *     protected static string $branchScopeRelation = 'invoice';
 *
 * The relation must be non-nullable — whereHas drops rows with no parent, and
 * for a line item that is right.
 */
trait ScopedThroughBranch
{
    public static function bootScopedThroughBranch(): void
    {
        static::addGlobalScope(new BranchScopeThrough(static::$branchScopeRelation));
    }

    public function scopeWithoutBranchScope(Builder $query): Builder
    {
        return $query->withoutGlobalScope(BranchScopeThrough::class);
    }

    public static function acrossBranches(callable $callback): mixed
    {
        return app(BranchScopeState::class)->withoutScope($callback);
    }
}
