<?php

namespace App\Models;

use App\Models\Traits\HasAuditFields;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class StockItem extends Model
{
    use HasFactory, SoftDeletes, HasAuditFields;

    protected $table = 'stock_items';

    /**
     * Status constants
     */
    public const STATUS_ACTIVE = 'active';
    public const STATUS_INACTIVE = 'inactive';
    public const STATUS_DISCONTINUED = 'discontinued';

    protected $fillable = [
        'item_code',
        'category_id',
        'item_name',
        'description',
        'uom',
        'quantity',
        'min_stock',
        'max_stock',
        'sgst',
        'cgst',
        'igst',
        'hsn_code',
        'status',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'quantity' => 'decimal:2',
        'min_stock' => 'decimal:2',
        'max_stock' => 'decimal:2',
        'sgst' => 'decimal:2',
        'cgst' => 'decimal:2',
        'igst' => 'decimal:2',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    protected $attributes = [
        'status' => self::STATUS_ACTIVE,
        'quantity' => 0,
        'min_stock' => 0,
    ];

    // ──────────────────────────────────────────────────────────────────────────
    // RELATIONSHIPS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Get the category this item belongs to
     */
    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    // Note: creator() relationship is provided by HasAuditFields trait

    // ──────────────────────────────────────────────────────────────────────────
    // SCOPES
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Filter by active status
     */
    public function scopeActive(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_ACTIVE);
    }

    /**
     * Filter by inactive status
     */
    public function scopeInactive(Builder $query): Builder
    {
        return $query->where('status', self::STATUS_INACTIVE);
    }

    /**
     * Filter low stock items
     */
    public function scopeLowStock(Builder $query): Builder
    {
        return $query->whereColumn('quantity', '<=', 'min_stock')
            ->where('status', self::STATUS_ACTIVE);
    }

    /**
     * Filter by category
     */
    public function scopeInCategory(Builder $query, int $categoryId): Builder
    {
        return $query->where('category_id', $categoryId);
    }

    /**
     * Search by name or code
     */
    public function scopeSearch(Builder $query, string $term): Builder
    {
        return $query->where(function ($q) use ($term) {
            $q->where('item_name', 'like', "%{$term}%")
                ->orWhere('item_code', 'like', "%{$term}%");
        });
    }

    /**
     * Order by item name
     */
    public function scopeOrderByName(Builder $query): Builder
    {
        return $query->orderBy('item_name', 'asc');
    }

    // ──────────────────────────────────────────────────────────────────────────
    // ACCESSORS & HELPERS
    // ──────────────────────────────────────────────────────────────────────────

    /**
     * Get all valid statuses
     */
    public static function getStatuses(): array
    {
        return [
            self::STATUS_ACTIVE,
            self::STATUS_INACTIVE,
            self::STATUS_DISCONTINUED,
        ];
    }

    /**
     * Check if item is active
     */
    public function isActive(): bool
    {
        return $this->status === self::STATUS_ACTIVE;
    }

    /**
     * Check if stock is low
     */
    public function isLowStock(): bool
    {
        return $this->quantity <= $this->min_stock;
    }

    /**
     * Get total GST percentage
     */
    public function getTotalGstAttribute(): float
    {
        return ($this->sgst ?? 0) + ($this->cgst ?? 0);
    }

    /**
     * Adjust stock quantity
     */
    public function adjustStock(float $quantity, string $type = 'add'): self
    {
        if ($type === 'add') {
            $this->increment('quantity', $quantity);
        } else {
            $this->decrement('quantity', abs($quantity));
        }
        return $this->fresh();
    }

    /**
     * Check if stock is available for a given quantity
     */
    public function hasStock(float $requiredQuantity): bool
    {
        return $this->quantity >= $requiredQuantity;
    }
}
