<?php

namespace App\Models;

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

class Product extends Model
{
    use HasFactory;


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

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

        static::updating(function ($product) {
            if (empty($product->slug) && !empty($product->name)) {
                $product->slug = static::generateUniqueSlug($product->name);
            }
        });
    }

    protected static function generateUniqueSlug($name)
    {
        $slug = Str::slug($name);
        $count = static::where('slug', 'LIKE', "{$slug}%")->count();
        return $count ? "{$slug}-" . ($count + 1) : $slug;
    }


    use \App\Traits\ImageUploadTrait;

    protected $fillable = [
        'seller_id',
        'category_id',
        'name',
        'slug',
        'description',
        'price',
        'stock',
        'moq',
        'images_json',
        'specifications',
        'is_highlighted',
        'is_approved',
        'plan_limit',
        'currency',
    ];

    protected $casts = [
        'images_json' => 'array',
        'specifications' => 'array',
        'is_approved' => 'boolean',
    ];

    public function getFormattedPriceAttribute()
    {
        $symbol = $this->currency === 'USD' ? '$' : '₹';
        return $symbol . number_format($this->price, 2);
    }

    public function unit()
    {
        return $this->belongsTo(Unit::class);
    }

    public function seller()
    {
        return $this->belongsTo(Seller::class);
    }

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

    public function promotion()
    {
        return $this->hasOne(ProductPromotion::class)->where('status', 'active');
    }

    /**
     * Check if product is currently promoted
     */
    public function isPromoted(): bool
    {
        return $this->promotion()->exists() && $this->promotion->isActive();
    }

    /**
     * Get promotion badge text
     */
    public function getPromotionBadge(): ?string
    {
        if (!$this->isPromoted()) {
            return null;
        }

        return $this->promotion->package->badge_text;
    }

    /**
     * Scope to get only promoted products
     */
    public function scopePromoted($query)
    {
        return $query->whereHas('promotion', function($q) {
            $q->where('status', 'active')
              ->where('start_date', '<=', now())
              ->where('end_date', '>=', now());
        });
    }

    public function scopeActive($query)
    {
        // Assuming active means seller is active/verified? Or just product exists?
        // Usually products have an 'is_active' status. 
        // Prompt says "activeProducts()". 
        // Schema doesn't have 'is_active' on products. 
        // Maybe it relies on Seller status?
        return $query->whereHas('seller', function ($q) {
            $q->where('is_verified', true); // Example condition
        });
    }

    public function scopeVerifiedSellers($query)
    {
        return $query->whereHas('seller', function ($q) {
            $q->where('is_verified', true);
        });
    }

    public function scopeSubscribedSellers($query)
    {
        return $query->whereHas('seller', function ($q) {
            $q->whereHas('subscription', function ($sub) {
                $sub->where('status', 'active');
            });
        });
    }

    // Scout Searchable Structure
    public function toSearchableArray()
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'category' => $this->category->name,
            'price' => $this->price,
        ];
    }

    /**
     * Get the main image URL for the product.
     * Handles various formats of images_json (string, array, missing keys).
     */
    public function getMainImageAttribute()
    {
        $images = $this->images_json;

        // Fallback Image Constant
        $fallback = 'https://placehold.co/400x400?text=No+Image';

        // Helper to check and return
        $checkAndReturn = function($path) use ($fallback) {
            if (empty($path)) return $fallback;
            // If it's already a full URL, return it
            if (filter_var($path, FILTER_VALIDATE_URL)) return $path;
            
            // Check if file exists in public storage
            if (\Illuminate\Support\Facades\Storage::disk('public')->exists($path)) {
                return asset('storage/' . $path);
            }
            
            // If not in storage, maybe it's a direct public path (less common with storage link)
            // But for safety, if we can't verify it, valid URL fallback is better than broken link.
            // For now, let's assume if it's not in storage, we treat it as missing unless it looks like an asset path
            return $fallback;
        };

        // Handle string (JSON or raw path)
        if (is_string($images)) {
            $decoded = json_decode($images, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                $images = $decoded;
            } else {
                return $checkAndReturn($images);
            }
        }

        // Handle Array
        if (is_array($images) && !empty($images)) {
            $firstImage = $images[0];
            
            if (is_array($firstImage)) {
                if (!empty($firstImage['thumbnail'])) {
                    return $checkAndReturn($firstImage['thumbnail']);
                }
                if (!empty($firstImage['original'])) {
                    return $checkAndReturn($firstImage['original']);
                }
            }
            
            if (is_string($firstImage)) {
                return $checkAndReturn($firstImage);
            }
        }

        return $fallback;
    }
    public function analytics()
    {
        return $this->hasMany(Analytic::class, 'source_id')->where('type', 'product_view');
    }
}
