<?php

namespace App\Models;

use App\Enums\CommissionType;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;

class Product extends Model
{
    use HasFactory;
    use SoftDeletes;
    use LogsActivity;

    protected $fillable = [
        'category_id',
        'partner_id',
        'name',
        'slug',
        'description',
        'buy_price',
        'sell_price',
        'commission_type',
        'commission_value',
        'unit',
        'image',
        'is_active',
        'is_featured',
        'sort_order',
        'stock',
    ];

    protected function casts(): array
    {
        return [
            'buy_price'        => 'decimal:2',
            'sell_price'       => 'decimal:2',
            'commission_type'  => CommissionType::class,
            'commission_value' => 'decimal:2',
            'is_active'        => 'boolean',
            'is_featured'      => 'boolean',
            'sort_order'       => 'integer',
            'stock'            => 'integer',
        ];
    }

    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->logOnly(['name', 'sell_price', 'is_active', 'is_featured', 'sort_order', 'category_id', 'partner_id'])
            ->logOnlyDirty()
            ->useLogName('product');
    }

    // ── Lifecycle ─────────────────────────────────────────────────────────

    protected static function booted(): void
    {
        static::creating(function (self $product) {
            if (empty($product->slug)) {
                $product->slug = Str::slug($product->name);
            }
        });
    }

    // ── Relationships ─────────────────────────────────────────────────────

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

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

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

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

    // ── Commission Logic ──────────────────────────────────────────────────

    /**
     * Tipe komisi efektif:
     * Gunakan komisi produk jika diisi, fallback ke default partner.
     */
    public function effectiveCommissionType(): CommissionType
    {
        return $this->commission_type ?? $this->partner->default_commission_type;
    }

    /**
     * Nilai komisi efektif:
     * Gunakan komisi produk jika diisi, fallback ke default partner.
     */
    public function effectiveCommissionValue(): float
    {
        return (float) ($this->commission_value ?? $this->partner->default_commission_value);
    }

    /**
     * Hitung nominal komisi untuk sell_price saat ini.
     */
    public function calculateCommission(): float
    {
        $type  = $this->effectiveCommissionType();
        $value = $this->effectiveCommissionValue();

        return match ($type) {
            CommissionType::Percent => round($this->sell_price * $value / 100, 2),
            CommissionType::Fixed   => $value,
        };
    }

    /**
     * Margin Admin = sell_price - buy_price - commission
     */
    public function calculateMargin(): float
    {
        return $this->sell_price - $this->buy_price - $this->calculateCommission();
    }

    // ── Scopes ────────────────────────────────────────────────────────────

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

    /**
     * Apakah stok dikelola (bukan null).
     * stock = NULL → tidak dikelola (selalu dianggap tersedia)
     */
    public function isStockManaged(): bool
    {
        return $this->stock !== null;
    }

    /**
     * Apakah stok habis.
     * Hanya berlaku jika stok dikelola (tidak null).
     * stock = 0 → habis
     */
    public function isOutOfStock(): bool
    {
        return $this->isStockManaged() && $this->stock === 0;
    }

    public function scopeFeatured($query)
    {
        return $query->where('is_featured', true)->where('is_active', true);
    }

    /**
     * Urutan default untuk katalog:
     * sort_order ASC (0 = belum diatur, tampil paling belakang),
     * kemudian created_at DESC untuk produk baru.
     */
    public function scopeOrdered($query)
    {
        return $query->orderByRaw('CASE WHEN sort_order = 0 THEN 1 ELSE 0 END')
                     ->orderBy('sort_order')
                     ->orderByDesc('created_at');
    }
}
