<?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 RawMaterial extends Model
{
    use HasFactory, SoftDeletes, HasAuditFields;

    protected $table = 'raw_materials';

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

    protected $fillable = [
        'code',
        'name',
        'rm_grade',
        'iso_specification',
        'density',
        'raw_material_type',
        'mechanical_properties',
        'chemical_properties',
        'quantity',
        'min_stock',
        'uom',
        'status',
        'product_type_id',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'density' => 'decimal:4',
        'quantity' => 'decimal:2',
        'min_stock' => 'decimal:2',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

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

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

    /**
     * Get the files associated with this raw material
     */
    public function files()
    {
        return $this->hasMany(RawMaterialFile::class);
    }

    /**
     * Get the product type for this raw material
     */
    public function productType()
    {
        return $this->belongsTo(ProductType::class, 'product_type_id');
    }

    // 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 product type
     */
    public function scopeOfType(Builder $query, int $typeId): Builder
    {
        return $query->where('product_type_id', $typeId);
    }

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

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

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

    /**
     * Check if material 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 display name (prefer name, fallback to rm_grade)
     */
    public function getDisplayNameAttribute(): string
    {
        return $this->name ?: $this->rm_grade ?: 'Unnamed Material';
    }

    /**
     * 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();
    }
}
