<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Product extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'category_id', 'name', 'sku', 'barcode', 'description',
        'image', 'cost_price', 'selling_price', 'min_selling_price',
        'unit', 'stock', 'min_stock', 'track_stock',
        'is_active', 'is_featured', 'variants',
    ];

    protected $casts = [
        'cost_price'       => 'decimal:2',
        'selling_price'    => 'decimal:2',
        'min_selling_price'=> 'decimal:2',
        'is_active'        => 'boolean',
        'is_featured'      => 'boolean',
        'track_stock'      => 'boolean',
        'variants'         => 'array',
    ];

    // Relasi
    public function category()
    {
        return $this->belongsTo(Category::class);
    }

    public function transactionItems()
    {
        return $this->hasMany(TransactionItem::class);
    }

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

    // Scope
    public function scopeActive($query)
    {
        return $query->where('is_active', true);
    }

    public function scopeLowStock($query)
    {
        return $query->whereColumn('stock', '<=', 'min_stock')->where('track_stock', true);
    }

    public function scopeSearch($query, $term)
    {
        return $query->where(function ($q) use ($term) {
            $q->where('name', 'like', "%{$term}%")
              ->orWhere('sku', 'like', "%{$term}%")
              ->orWhere('barcode', 'like', "%{$term}%");
        });
    }

    // Accessor
    public function getMarginAttribute(): float
    {
        if ($this->selling_price == 0) return 0;
        return (($this->selling_price - $this->cost_price) / $this->selling_price) * 100;
    }

    public function getProfitAttribute(): float
    {
        return $this->selling_price - $this->cost_price;
    }

    public function getIsLowStockAttribute(): bool
    {
        return $this->track_stock && $this->stock <= $this->min_stock;
    }

    public function getImageUrlAttribute(): string
    {
        if ($this->image && file_exists(public_path('storage/' . $this->image))) {
            return asset('storage/' . $this->image);
        }
        return asset('images/product-placeholder.png');
    }

    // Metode
    public function updateStock(int $change, string $type, User $user, ?int $transactionId = null, string $reason = '')
    {
        $before = $this->stock;
        $this->stock += $change;
        $this->save();

        StockMovement::create([
            'product_id'      => $this->id,
            'user_id'         => $user->id,
            'transaction_id'  => $transactionId,
            'type'            => $type,
            'quantity_before' => $before,
            'quantity_change' => $change,
            'quantity_after'  => $this->stock,
            'reason'          => $reason,
        ]);

        return $this;
    }

    // Generate SKU otomatis
    public static function generateSku(string $prefix = 'PRD'): string
    {
        $last = self::withTrashed()->latest('id')->first();
        $num = $last ? $last->id + 1 : 1;
        return strtoupper($prefix) . '-' . str_pad($num, 5, '0', STR_PAD_LEFT);
    }
}
