<?php

namespace App\Models;

use App\Traits\LogsPartHistory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Part extends Model
{
    /** @use HasFactory<\Database\Factories\PartFactory> */
    use HasFactory, LogsPartHistory;

    protected $fillable = [
        'part_number',
        'name',
        'description',
        'manufacturer',
        'category',
        'cost_price',
        'sell_price',
        'quantity_on_hand',
        'minimum_stock_level',
        'maximum_stock_level',
        'location',
        'supplier_id',
        'supplier_part_number',
        'lead_time_days',
        'status',
        'barcode',
        'weight',
        'dimensions',
        'warranty_period',
        'image',
    ];

    protected $casts = [
        'cost_price' => 'decimal:2',
        'sell_price' => 'decimal:2',
        'quantity_on_hand' => 'integer',
        'minimum_stock_level' => 'integer',
        'maximum_stock_level' => 'integer',
        'lead_time_days' => 'integer',
        'weight' => 'decimal:2',
    ];

    public function serviceOrders(): BelongsToMany
    {
        return $this->belongsToMany(ServiceOrder::class, 'service_items')
            ->withPivot(['quantity', 'price', 'total'])
            ->withTimestamps();
    }

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

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

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

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

    public function isLowStock(): bool
    {
        return $this->quantity_on_hand <= $this->minimum_stock_level;
    }

    public function getMarkupPercentageAttribute()
    {
        if ($this->cost_price > 0) {
            return round((($this->sell_price - $this->cost_price) / $this->cost_price) * 100, 2);
        }
        return 0;
    }

    public function getStockStatusAttribute(): string
    {
        if ($this->quantity_on_hand <= 0) {
            return 'out_of_stock';
        } elseif ($this->quantity_on_hand <= $this->minimum_stock_level) {
            return 'low_stock';
        } elseif ($this->quantity_on_hand >= $this->maximum_stock_level) {
            return 'overstock';
        }
        return 'in_stock';
    }

    public function getStockStatusColorAttribute(): string
    {
        return match($this->stock_status) {
            'out_of_stock' => 'text-red-600 dark:text-red-400',
            'low_stock' => 'text-orange-600 dark:text-orange-400',
            'overstock' => 'text-purple-600 dark:text-purple-400',
            'in_stock' => 'text-green-600 dark:text-green-400',
            default => 'text-gray-600 dark:text-gray-400',
        };
    }

    public function getStockValueAttribute(): float
    {
        return $this->quantity_on_hand * $this->cost_price;
    }

    public function needsReorder(): bool
    {
        return $this->quantity_on_hand <= $this->minimum_stock_level;
    }

    public function scopeLowStock($query)
    {
        return $query->whereColumn('quantity_on_hand', '<=', 'minimum_stock_level');
    }

    public function scopeOutOfStock($query)
    {
        return $query->where('quantity_on_hand', '<=', 0);
    }

    public function scopeByCategory($query, $category)
    {
        return $query->where('category', $category);
    }

    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }
}
