<?php

namespace App\Models\Product;

use App\Models\Agency\Agency;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Product extends Model
{
    use SoftDeletes;

    protected $fillable = [
        'agency_id',
        'product_type_id',
        'primary_marketplace_id',
        'productable_type',
        'productable_id',
        'code',
        'name',
        'slug',
        'description',
        'base_price',
        'currency',
        'is_active',
        'is_featured',
        'is_bookable',
        'published_at',
        'view_count',
        'booking_count',
        'created_by',
        'updated_by',
    ];

    protected $casts = [
        'is_active' => 'boolean',
        'is_featured' => 'boolean',
        'is_bookable' => 'boolean',
        'published_at' => 'datetime',
        'base_price' => 'decimal:2',
    ];

    // Polymorphic relationship
    public function productable()
    {
        return $this->morphTo();
    }

    public function agency()
    {
        return $this->belongsTo(Agency::class);
    }

    public function productType()
    {
        return $this->belongsTo(ProductType::class);
    }

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

    public function marketplaces()
    {
        return $this->belongsToMany(\App\Models\Agency\Marketplace::class, 'product_marketplaces', 'product_id', 'marketplace_id')->withTimestamps();
    }

    /** Ana pazar: tarih fiyat matrisinde temel alınan, ana fiyatın okunduğu pazaryeri. */
    public function primaryMarketplace()
    {
        return $this->belongsTo(\App\Models\Agency\Marketplace::class, 'primary_marketplace_id');
    }

    public function marketplaceTranslations()
    {
        return $this->hasMany(ProductMarketplaceTranslation::class);
    }

    public function marketplacePrices()
    {
        return $this->hasMany(ProductMarketplacePrice::class);
    }

    public function creator()
    {
        return $this->belongsTo(User::class, 'created_by');
    }

    public function updater()
    {
        return $this->belongsTo(User::class, 'updated_by');
    }

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

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

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

    public function scopeByAgency($query, $agencyId)
    {
        return $query->where('agency_id', $agencyId);
    }

    public function scopeByProductType($query, $productTypeId)
    {
        return $query->where('product_type_id', $productTypeId);
    }

    // Helper methods
    public function getRouteKeyName()
    {
        return 'slug';
    }

    /**
     * Benzersiz slug oluşturur
     * Aynı slug varsa sonuna -2, -3 gibi sayı ekler
     */
    public static function generateUniqueSlug(string $name, ?int $excludeId = null): string
    {
        $slug = \Illuminate\Support\Str::slug($name);
        $originalSlug = $slug;
        $counter = 2;

        $query = static::withTrashed()->where('slug', $slug);
        if ($excludeId) {
            $query->where('id', '!=', $excludeId);
        }

        while ($query->exists()) {
            $slug = $originalSlug . '-' . $counter;
            $query = static::withTrashed()->where('slug', $slug);
            if ($excludeId) {
                $query->where('id', '!=', $excludeId);
            }
            $counter++;
        }

        return $slug;
    }

    /**
     * Ürün no: acente + ürün tipi içinde 1'den başlayan düz sıra numarası.
     * products.code unique'i (agency_id, product_type_id, code) olduğu ve numara
     * otoritesi products olduğu için sonraki numara buradan hesaplanır; soft-delete
     * edilmiş satırlar da indekste yer tuttuğundan sorguya dahildir.
     */
    public static function generateUniqueCode(int $agencyId, int $productTypeId): string
    {
        return \App\Support\SequentialCode::next(
            static::withTrashed()
                ->where('agency_id', $agencyId)
                ->where('product_type_id', $productTypeId)
        );
    }

    public function isActive(): bool
    {
        return $this->is_active;
    }

    public function isBookable(): bool
    {
        return $this->is_bookable && $this->is_active;
    }

    public function incrementViewCount(): void
    {
        $this->increment('view_count');
    }

    public function incrementBookingCount(): void
    {
        $this->increment('booking_count');
    }
}
