<?php

namespace App\Models\Tour;

use App\Models\Agency\Agency;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;

class TourCategory extends Model
{
    use HasFactory, SoftDeletes;

    protected $fillable = [
        'agency_id',
        'is_master_category',
        'master_category_id',
        'parent_id',
        'level',
        'path',
        'code',
        'name',
        'slug',
        'description',
        'short_description',
        'image',
        'icon',
        'gallery',
        'sort_order',
        'color_code',
        'is_featured',
        'show_on_homepage',
        'meta_title',
        'meta_description',
        'meta_keywords',
        'meta_data',
        'settings',
        'filters',
        'is_active',
        'is_public',
        'view_count',
        'tour_count',
        'created_by',
        'updated_by',
    ];

    protected function casts(): array
    {
        return [
            'gallery' => 'array',
            'meta_data' => 'array',
            'settings' => 'array',
            'filters' => 'array',
            'is_master_category' => 'boolean',
            'is_featured' => 'boolean',
            'show_on_homepage' => 'boolean',
            'is_active' => 'boolean',
            'is_public' => 'boolean',
            'sort_order' => 'integer',
            'level' => 'integer',
            'view_count' => 'integer',
            'tour_count' => 'integer',
        ];
    }

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

    public function parent()
    {
        return $this->belongsTo(TourCategory::class, 'parent_id');
    }

    public function children()
    {
        return $this->hasMany(TourCategory::class, 'parent_id')->orderBy('sort_order');
    }

    /**
     * Ana kategori ilişkisi (acente kategorileri için)
     */
    public function masterCategory()
    {
        return $this->belongsTo(TourCategory::class, 'master_category_id');
    }

    /**
     * Bu ana kategoriye bağlı acente kategorileri
     */
    public function agencySubcategories()
    {
        return $this->hasMany(TourCategory::class, 'master_category_id')
            ->whereNotNull('agency_id')
            ->orderBy('agency_id')
            ->orderBy('sort_order');
    }

    public function allChildren()
    {
        return $this->children()->with('allChildren');
    }

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

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

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

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

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

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

    public function scopeRootCategories($query)
    {
        return $query->whereNull('parent_id');
    }

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

    public function scopeByLevel($query, $level)
    {
        return $query->where('level', $level);
    }

    /**
     * Sadece ana kategorileri getir
     */
    public function scopeMasterCategories($query)
    {
        return $query->where('is_master_category', true)->whereNull('agency_id');
    }

    /**
     * Sadece acente kategorilerini getir
     */
    public function scopeAgencyCategories($query, $agencyId = null)
    {
        $query = $query->where('is_master_category', false)->whereNotNull('agency_id');

        if ($agencyId) {
            $query->where('agency_id', $agencyId);
        }

        return $query;
    }

    /**
     * Belirli bir ana kategoriye bağlı kategorileri getir
     */
    public function scopeByMasterCategory($query, $masterCategoryId)
    {
        return $query->where('master_category_id', $masterCategoryId);
    }

    public function isRoot()
    {
        return is_null($this->parent_id);
    }

    public function hasChildren()
    {
        return $this->children()->exists();
    }

    /**
     * Ana kategori mi kontrol eder
     */
    public function isMasterCategory()
    {
        return $this->is_master_category === true;
    }

    /**
     * Acente kategorisi mi kontrol eder
     */
    public function isAgencyCategory()
    {
        return $this->is_master_category === false && !is_null($this->agency_id);
    }

    /**
     * Tam yol bilgisini döndürür (Ana Kategori > Alt Kategori > Alt Alt Kategori)
     */
    public function getFullPathAttribute()
    {
        $path = [];

        // Ana kategoriyi ekle
        if ($this->master_category_id) {
            $path[] = $this->masterCategory->name;
        }

        // Parent zincirini ekle
        if ($this->parent_id && $this->parent) {
            $parentPath = $this->getParentPath($this->parent);
            $path = array_merge($path, $parentPath);
        }

        // Kendini ekle
        $path[] = $this->name;

        return implode(' > ', $path);
    }

    /**
     * Parent path helper
     */
    private function getParentPath($category)
    {
        $path = [];

        if ($category->parent_id && $category->parent) {
            $path = $this->getParentPath($category->parent);
        }

        $path[] = $category->name;

        return $path;
    }

    public function getFullNameAttribute()
    {
        if ($this->isRoot()) {
            return $this->name;
        }

        return $this->parent->full_name . ' > ' . $this->name;
    }

    public function tours()
    {
        return $this->belongsToMany(
            Tour::class,
            'tour_category_tour',
            'category_id',
            'tour_id'
        );
    }
    public function activeTours()
    {
        return $this->tours()
            ->active()
            ->public()
            ->bookable();
    }

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

        static::creating(function ($category) {

            // Slug oluşturma - Ana kategori için unique, acente kategorisi için agency scope'lu
            if (empty($category->slug)) {
                $baseSlug = Str::slug($category->name);

                if ($category->is_master_category || is_null($category->agency_id)) {
                    // Ana kategori - Global unique slug
                    $category->slug = $baseSlug;
                } else {
                    // Acente kategorisi - Agency scoped slug
                    $category->slug = $category->agency_id . '-' . $baseSlug;

                    // Slug collision check
                    $count = 1;
                    while (static::where('slug', $category->slug)->exists()) {
                        $category->slug = $category->agency_id . '-' . $baseSlug . '-' . $count;
                        $count++;
                    }
                }
            }

            if (empty($category->code)) {
                $category->code = 'CAT' . sprintf('%05d', static::count() + 1);
            }

            // Hiyerarşi hesaplama
            if ($category->parent_id) {
                $parent = static::find($category->parent_id);
                $category->level = $parent->level + 1;
                $category->path = $parent->path ? $parent->path . ',' . $parent->id : $parent->id;

                // Eğer parent bir acente kategorisi ise master_category_id'yi parent'tan al
                if (!$category->master_category_id && $parent->master_category_id) {
                    $category->master_category_id = $parent->master_category_id;
                }
            } else if (!$category->is_master_category && $category->master_category_id) {
                // Ana kategori altında doğrudan kategori oluşturuluyorsa
                $masterCategory = static::find($category->master_category_id);
                if ($masterCategory) {
                    $category->level = 1; // Ana kategorinin bir alt seviyesi
                }
            }

            if (auth()->check()) {
                $category->created_by = auth()->id();
            }
        });

        static::updating(function ($category) {
            if (auth()->check()) {
                $category->updated_by = auth()->id();
            }
        });
    }
}
