<?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
    {
        if (app()->runningInConsole()) {
            return null;
        }

        if (app()->bound('session') && session()->has('active_branch_id')) {
            $sessionBranch = session('active_branch_id');

            // A null in the session is the deliberate "all branches" mode, so
            // fall through to the user's own branch rather than storing null.
            if ($sessionBranch) {
                return (int) $sessionBranch;
            }
        }

        return auth()->user()?->branch_id;
    }

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