<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class ProductBatch extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'product_id', 'supplier_id', 'purchase_id',
        'batch_number', 'lot_number', 'serial_number',
        'manufacture_date', 'expiry_date',
        'initial_quantity', 'current_quantity', 'reserved_quantity',
        'batch_cost_price', 'batch_sale_price',
        'warehouse_location',
        'quality_status', 'quality_notes',
        'notes', 'created_by',
    ];

    protected $casts = [
        'manufacture_date' => 'date',
        'expiry_date' => 'date',
        'initial_quantity' => 'integer',
        'current_quantity' => 'integer',
        'reserved_quantity' => 'integer',
        'batch_cost_price' => 'decimal:2',
        'batch_sale_price' => 'decimal:2',
    ];

    protected $appends = [
        'available_quantity',
        'days_to_expiry',
        'expiry_status',
        'is_expired',
        'is_expiring_soon',
    ];

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

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

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

    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function stockMovements(): HasMany
    {
        return $this->hasMany(BatchStockMovement::class);
    }

    /**
     * Accessors
     */
    public function getAvailableQuantityAttribute(): int
    {
        return $this->current_quantity - $this->reserved_quantity;
    }

    public function getDaysToExpiryAttribute(): ?int
    {
        if (!$this->expiry_date) return null;
        return now()->diffInDays($this->expiry_date, false);
    }

    public function getExpiryStatusAttribute(): string
    {
        if (!$this->expiry_date) return 'no_expiry';
        
        $days = $this->days_to_expiry;
        
        if ($days < 0) return 'expired';
        if ($days <= 30) return 'expiring_soon';
        return 'valid';
    }

    public function getIsExpiredAttribute(): bool
    {
        return $this->expiry_status === 'expired';
    }

    public function getIsExpiringSoonAttribute(): bool
    {
        return $this->expiry_status === 'expiring_soon';
    }

    /**
     * Methods
     */
    public function reserve(int $quantity): bool
    {
        if ($this->available_quantity < $quantity) {
            return false;
        }
        
        $this->increment('reserved_quantity', $quantity);
        return true;
    }

    public function release(int $quantity): bool
    {
        if ($this->reserved_quantity < $quantity) {
            return false;
        }
        
        $this->decrement('reserved_quantity', $quantity);
        return true;
    }

    /**
     * Scopes
     */
    public function scopeActive($query)
    {
        return $query->where('current_quantity', '>', 0)
                     ->where('quality_status', 'approved');
    }

    public function scopeExpired($query)
    {
        return $query->where('expiry_date', '<', now())
                     ->where('current_quantity', '>', 0);
    }

    public function scopeExpiringSoon($query, $days = 30)
    {
        return $query->where('expiry_date', '>=', now())
                     ->where('expiry_date', '<=', now()->addDays($days))
                     ->where('current_quantity', '>', 0);
    }

    public function scopeByProduct($query, $productId)
    {
        return $query->where('product_id', $productId);
    }

    public function scopeBySupplier($query, $supplierId)
    {
        return $query->where('supplier_id', $supplierId);
    }
}