<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Product extends Model
{
    use HasFactory;

    protected $fillable = [
        'category_id',
        'name',
        'slug',
        'sku',
        'short_description',
        'description',
        'price',
        'compare_price',
        'image',
        'stock_quantity',
        'has_variants',
        'is_active',
        'is_featured',
    ];

    protected $casts = [
        'price' => 'decimal:2',
        'compare_price' => 'decimal:2',
        'has_variants' => 'boolean',
        'is_active' => 'boolean',
        'is_featured' => 'boolean',
    ];

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

    public function images(): HasMany
    {
        return $this->hasMany(ProductImage::class)->orderBy('sort_order');
    }

    public function variantAttributes(): HasMany
    {
        return $this->hasMany(VariantAttribute::class)->orderBy('sort_order');
    }

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

    /**
     * Eager-load everything needed to render / evaluate variants.
     */
    public function loadVariantData(): static
    {
        return $this->load([
            'variantAttributes.values',
            'variants.values.attribute',
            'variants.values.value',
            'variants.images',
        ]);
    }

    /**
     * Build the data the storefront JS needs: attributes with their values and
     * the list of concrete, purchasable combinations.
     */
    public function variantMatrix(): array
    {
        $attributes = $this->variantAttributes->map(fn (VariantAttribute $attr) => [
            'name' => $attr->name,
            'values' => $attr->values->pluck('value')->all(),
        ])->all();

        $combinations = $this->variants->map(function (ProductVariant $variant) {
            return [
                'id' => $variant->id,
                'options' => $variant->optionMap(),
                'price' => (float) $variant->price,
                'compare_price' => $variant->compare_price !== null ? (float) $variant->compare_price : null,
                'stock' => (int) $variant->stock_quantity,
                'in_stock' => $variant->is_active && $variant->stock_quantity > 0,
                'image' => $variant->images->first()
                    ? asset('storage/'.$variant->images->first()->image)
                    : null,
                'images' => $variant->images
                    ->map(fn (ProductVariantImage $img) => asset('storage/'.$img->image))
                    ->all(),
            ];
        })->all();

        return [
            'attributes' => $attributes,
            'combinations' => $combinations,
        ];
    }

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

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

    public function isInStock(): bool
    {
        return $this->stock_quantity > 0;
    }

    public function getDiscountPercentAttribute(): ?int
    {
        if ($this->compare_price && $this->compare_price > $this->price) {
            return (int) round((($this->compare_price - $this->price) / $this->compare_price) * 100);
        }

        return null;
    }
}
