<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;

class Product extends Model
{
    use HasFactory;

    protected $fillable = [
        'name', 'slug', 'description', 'short_description',
        'price', 'compare_price', 'stock_quantity', 'track_stock',
        'allow_preorder', 'preorder_note', 'preorder_days', 'status',
        'is_featured', 'is_bestseller', 'loyalty_points_earn', 'weight_grams',
        'meta_title', 'meta_description',
    ];

    protected $appends = ['is_in_stock'];

    protected function casts(): array
    {
        return [
            'price' => 'decimal:2',
            'compare_price' => 'decimal:2',
            'stock_quantity' => 'integer',
            'track_stock' => 'boolean',
            'allow_preorder' => 'boolean',
            'preorder_days' => 'integer',
            'is_featured' => 'boolean',
            'is_bestseller' => 'boolean',
            'loyalty_points_earn' => 'integer',
            'weight_grams' => 'integer',
        ];
    }

    public function categories(): BelongsToMany
    {
        return $this->belongsToMany(ProductCategory::class, 'product_category_pivot', 'product_id', 'category_id');
    }

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

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

    public function primaryImage(): HasOne
    {
        return $this->hasOne(ProductImage::class)->where('is_primary', true);
    }

    public function labReports(): HasMany
    {
        return $this->hasMany(LabReport::class)->orderByDesc('test_date');
    }

    public function activeLabReport(): HasOne
    {
        return $this->hasOne(LabReport::class)->where('is_active', true)->latestOfMany('test_date');
    }

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

    public function getIsInStockAttribute(): bool
    {
        // If variants are loaded, stock lives on each variant — check if any has stock
        if ($this->relationLoaded('variants') && $this->variants->isNotEmpty()) {
            return $this->variants->contains(fn($v) => $v->stock_quantity > 0);
        }

        // variants_count injected via withCount() — no variants means product-level stock
        if (isset($this->attributes['variants_count']) && (int) $this->attributes['variants_count'] > 0) {
            // Variants exist but aren't loaded — can't determine per-variant stock here,
            // fall back to product-level field as a safe default
            return !$this->track_stock || $this->stock_quantity > 0;
        }

        return !$this->track_stock || $this->stock_quantity > 0;
    }

    public function getLoyaltyPointsEarnAttribute(): int
    {
        $stored = $this->attributes['loyalty_points_earn'] ?? null;
        return $stored !== null ? (int) $stored : (int) ($this->price * 100);
    }
}
