<?php

namespace App\Models;

use App\Models\Catalog\Product;
use App\Models\Concerns\BelongsToTenant;
use App\Models\Concerns\BranchScoped;
use App\Models\Scopes\BranchScope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

/**
 * Current stock level per (branch, product). This is the single source of
 * truth for available stock.
 *
 * Mutations are exclusive to App\Services\StockMovementService — direct
 * writes to `quantity` outside the service violate the Golden Rule
 * (see docs/workflows/stock-movement.md).
 *
 * Branch-scoped for read access (e.g. dashboard/report stock totals), but
 * every lookup keyed by an explicit $branchId parameter — not the acting
 * user's current branch context — MUST bypass the scope with
 * `withoutGlobalScope(BranchScope::class)`, since a stock transfer's "to"
 * branch is routinely different from the acting user's context branch; see
 * {@see quantityFor()}, {@see totalFor()}, and StockMovementService::record().
 */
class BranchStock extends Model
{
    use BelongsToTenant, BranchScoped;

    protected $table = 'branch_stock';

    public $timestamps = true;

    protected $fillable = [
        'branch_id',
        'product_id',
        'quantity',
    ];

    protected function casts(): array
    {
        return [
            'quantity' => 'decimal:4',
            'branch_id' => 'integer',
            'product_id' => 'integer',
        ];
    }

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

    /**
     * Current quantity of a product at a single branch (0 if no row exists).
     * $branchId is an explicit business parameter, not necessarily the
     * caller's current branch context (e.g. a stock transfer's destination
     * branch) — callers are responsible for their own access check, so this
     * bypasses BranchScope rather than silently AND-ing in an unrelated
     * context filter.
     */
    public static function quantityFor(int $branchId, int $productId): float
    {
        return (float) (static::query()
            ->withoutGlobalScope(BranchScope::class)
            ->where('branch_id', $branchId)
            ->where('product_id', $productId)
            ->value('quantity') ?? 0);
    }

    /**
     * Current quantity of a product across all branches.
     */
    public static function totalFor(int $productId): float
    {
        return (float) (static::query()
            ->withoutGlobalScope(BranchScope::class)
            ->where('product_id', $productId)
            ->sum('quantity'));
    }
}
