<?php

namespace App\Models;

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

class Product extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'name',
        'slug',
        'sku',
        'barcode',
        'description',
        'category_id',
        'brand_id',
        'price',
        'compare_at_price',
        'cost_price',
        'currency',
        'images',
        'sizes',
        'colors',
        'materials',
        'weight',
        'dimensions',
        'is_active',
        'is_featured',
        'is_new',
        'rating',
        'reviews_count',
        'views_count',
        'sales_count',
        'meta_title',
        'meta_description',
        'meta_keywords',
    ];

    protected $casts = [
        'price' => 'decimal:2',
        'compare_at_price' => 'decimal:2',
        'cost_price' => 'decimal:2',
        'weight' => 'decimal:2',
        'rating' => 'decimal:2',
        'images' => 'array',
        'sizes' => 'array',
        'colors' => 'array',
        'materials' => 'array',
        'dimensions' => 'array',
        'is_active' => 'boolean',
        'is_featured' => 'boolean',
        'is_new' => 'boolean',
    ];

    protected $appends = [];

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

    public function brand()
    {
        return $this->belongsTo(Brand::class);
    }

    public function variations()
    {
        return $this->hasMany(ProductVariation::class);
    }

    public function stock()
    {
        return $this->hasMany(Stock::class);
    }

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

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

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

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

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

    // Accessors
    public function getImageAttribute()
    {
        return $this->images[0] ?? null;
    }

    public function getDiscountAttribute()
    {
        if (!$this->compare_at_price) {
            return 0;
        }
        return $this->compare_at_price - $this->price;
    }

    public function getDiscountPercentageAttribute()
    {
        if (!$this->compare_at_price || $this->compare_at_price == 0) {
            return 0;
        }
        return round((($this->compare_at_price - $this->price) / $this->compare_at_price) * 100);
    }

    public function getHasVariationsAttribute()
    {
        return $this->variations()->count() > 0;
    }

    public function getVariationsCountAttribute()
    {
        return $this->variations()->count();
    }

    public function getTotalStockAttribute()
    {
        if ($this->has_variations) {
            return $this->variations()->sum('stock');
        }
        return $this->stock()->sum('quantity');
    }

    public function getAvailableStockAttribute()
    {
        if ($this->has_variations) {
            $total = 0;
            foreach ($this->variations as $variation) {
                $total += $variation->getAvailableStock();
            }
            return $total;
        }
        
        return $this->stock()->get()->sum(function ($stock) {
            return $stock->available_quantity;
        });
    }

    // Methods
    public function getVariationsByStore($storeId)
    {
        return $this->variations()
            ->with(['stock' => function ($query) use ($storeId) {
                $query->where('store_id', $storeId);
            }])
            ->get();
    }

    public function getStockByStore($storeId)
    {
        if ($this->has_variations) {
            return $this->getVariationsByStore($storeId);
        }
        
        return $this->stock()->where('store_id', $storeId)->first();
    }

    public function syncVariations(array $variations)
    {
        // Remover variações antigas
        $this->variations()->delete();
        
        // Criar novas variações
        foreach ($variations as $variation) {
            $this->variations()->create([
                'size' => $variation['size'],
                'color' => $variation['color'],
                'color_hex' => $variation['color_hex'] ?? '#000000',
                'sku' => $variation['sku'],
                'price_adjustment' => $variation['price_adjustment'] ?? 0,
                'stock' => $variation['stock'] ?? 0,
            ]);
        }
        
        // Atualizar campos sizes e colors para compatibilidade com frontend
        $this->updateSizesAndColorsFromVariations();
    }
    
    public function updateSizesAndColorsFromVariations()
    {
        $sizes = $this->variations()->pluck('size')->unique()->values()->toArray();
        $colors = $this->variations()
            ->select('color', 'color_hex')
            ->distinct()
            ->get()
            ->map(function ($item) {
                return ['name' => $item->color, 'hex' => $item->color_hex];
            })
            ->values()
            ->toArray();
        
        $this->update([
            'sizes' => $sizes,
            'colors' => $colors,
        ]);
    }

    // Events
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($product) {
            if (!$product->slug) {
                $product->slug = Str::slug($product->name);
            }
        });

        // Ao deletar o produto, deletar também as variações e estoques
        static::deleting(function ($product) {
            $product->variations()->delete();
            $product->stock()->delete();
        });
    }
}