<?php

namespace App\Models;

use App\Models\Concerns\BelongsToUser;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class Vente extends Model
{
    use BelongsToUser, HasFactory, SoftDeletes;

    protected $guarded = [];

    protected $casts = [
        'date_vente' => 'date',
        'quantite' => 'integer',
        'montant' => 'decimal:0',
        'montant_paye' => 'decimal:0',
    ];

    public const STATUT_PAYE = 'paye';
    public const STATUT_PARTIELLEMENT = 'partiellement';
    public const STATUT_EN_ATTENTE = 'en_attente';

    public function getMontantRestantAttribute(): float
    {
        return max(0, (float) $this->montant - (float) $this->montant_paye);
    }

    public function isPaye(): bool
    {
        return $this->statut_paiement === self::STATUT_PAYE;
    }

    public function isPartiellementPaye(): bool
    {
        return $this->statut_paiement === self::STATUT_PARTIELLEMENT;
    }

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

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

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

    public function paiements()
    {
        return $this->hasMany(Paiement::class);
    }

    /**
     * Générer la référence de la vente lors de la création
     */
    protected static function booted()
    {
        static::creating(function ($vente) {
            if (empty($vente->reference)) {
                $vente->reference = 'VNT-00' . strtoupper(Str::random(2));
            }
        });
    }

    /**
     * Calculer le stock actuel d'un produit dans un magasin
     * @param int $produitId
     * @param int $magasinId
     * @return int le stock actuel du produit dans le magasin
     */
    public static function stockActuel($produitId, $magasinId)
    {
        return (int) self::where('produit_id', $produitId)
            ->where('magasin_id', $magasinId)
            ->lockForUpdate()
            ->selectRaw("
                    COALESCE(SUM(
                        CASE WHEN type = 'entree' THEN quantite
                             WHEN type = 'sortie' THEN -quantite
                        END
                    ), 0) as stock
                ")
            ->value('stock');
    }
}
