<?php

namespace Daylight\Core\Models\Translations;

use Daylight\Core\Models\Category;
use Daylight\Core\Modules\MediaLibrary\Models\Concerns\InteractsWithMedia;
use Daylight\Core\Modules\PageBuilder\Concerns\InteractsWithComponents;
use Daylight\Core\Modules\PageBuilder\Contracts\HasComponents;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;

class CategoryTranslation extends Model implements HasComponents
{
    use HasSlug;
    use InteractsWithComponents;
    use InteractsWithMedia;

    protected $guarded = [];

    protected static function booted(): void
    {
        // Update nested_slug when slug changes
        static::saving(function (CategoryTranslation $translation) {
            if ($translation->isDirty('slug') || $translation->doesntExist()) {
                $translation->updateNestedSlug();
            }
        });

        // Update nested_slug for all related translations when saved
        static::saved(function (CategoryTranslation $translation) {
            if ($translation->wasRecentlyCreated && ! $translation->nested_slug) {
                $translation->updateNestedSlug();
                $translation->saveQuietly();
            }

            $translation->updateDescendantNestedSlugs();
        });
    }

    public function getSlugOptions(): SlugOptions
    {
        return SlugOptions::create()
            ->generateSlugsFrom('name')
            ->saveSlugsTo('slug')
            ->extraScope(fn ($builder) => $builder->where('locale', $this->locale)->whereCategoryId($this->category_id));
    }

    public function category(): BelongsTo
    {
        return $this->belongsTo(daylightModel('category'));
    }

    /**
     * Update the nested_slug for this translation based on ancestor slugs.
     */
    public function updateNestedSlug(): void
    {
        $category = $this->category()->with('ancestorsAndSelf.translations')->first();

        $this->nested_slug = $category->ancestorsAndSelf
            ->reverse()
            ->map(function ($ancestor) {
                return $ancestor->translations
                    ->where('locale', $this->locale)
                    ->first()?->slug;
            })
            ->filter()
            ->join('/');
    }

    /**
     * Update nested_slug for all descendant category translations.
     */
    public function updateDescendantNestedSlugs(): void
    {
        $category = $this->category;

        // Get all descendants of this category
        $descendants = Category::query()
            ->where('parent_id', $category->id)
            ->orWhereHas('ancestors', fn ($q) => $q->where('id', $category->id))
            ->with('translations')
            ->get();

        foreach ($descendants as $descendant) {
            foreach ($descendant->translations->where('locale', $this->locale) as $translation) {
                $translation->updateNestedSlug();
                $translation->saveQuietly(); // Save without triggering events to avoid recursion
            }
        }
    }
}
