<?php

namespace App\Domain\Shared\Traits;

use App\Domain\Identity\Models\Branch;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * Stamp the active branch onto transactional records at creation.
 *
 * Mirrors BelongsToAcademy's creating hook, but deliberately adds **no**
 * global scope: branch is a reporting lens, not an isolation boundary.
 * Console commands, cross-branch reports and the switcher's "all branches"
 * mode all need to read across branches, and a global scope would silently
 * break them.
 *
 * Use this only on records that represent an action — a payment, a sale, an
 * expense, an enrolment. Catalogue and configuration models (base prices,
 * pricing rules, products, employees) legitimately use a null branch to mean
 * "shared across every branch", and must not get this trait.
 */
trait BelongsToBranch
{
    public static function bootBelongsToBranch(): void
    {
        static::creating(function ($model) {
            if (! $model->branch_id) {
                $model->branch_id = static::resolveActiveBranchId();
            }
        });
    }

    /**
     * The branch the current actor is working in.
     *
     * Returns null rather than guessing when there is no request context —
     * queued jobs and scheduled commands run for the whole academy, and
     * inventing a branch there would misfile their records.
     */
    public static function resolveActiveBranchId(): ?int
    {
        return app(\App\Domain\Shared\Context\BranchContext::class)
            ->branchIdForStamping();
    }

    public function branch(): BelongsTo
    {
        return $this->belongsTo(Branch::class);
    }
}
