<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;

class BlogCategory extends Model
{
    public const DEFAULT_SLUG = 'دسته-بندی-نشده';

    protected $fillable = [
        'name', 'slug', 'parent_id', 'description', 'image', 'icon',
        'sort_order', 'is_active', 'is_protected',
        'seo_title', 'seo_description', 'seo_keywords',
    ];

    protected $casts = [
        'is_active'    => 'boolean',
        'is_protected' => 'boolean',
    ];

    public function getRouteKeyName(): string
    {
        return 'slug';
    }

    protected static function booted(): void
    {
        static::deleting(function (self $category) {
            if ($category->is_protected) {
                return false;
            }
        });
    }

    public static function default(): self
    {
        return static::firstOrCreate(
            ['slug' => self::DEFAULT_SLUG],
            [
                'name'         => 'دسته‌بندی نشده',
                'is_active'    => true,
                'is_protected' => true,
                'sort_order'   => 9999,
            ]
        );
    }

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

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

    public function posts(): HasMany
    {
        return $this->hasMany(BlogPost::class, 'category_id');
    }

    public function publishedPosts(): HasMany
    {
        return $this->hasMany(BlogPost::class, 'category_id')->published();
    }

    public function url(): string
    {
        return url('blog/' . $this->slug);
    }

    public static function flatTree(?int $excludeId = null): array
    {
        $all = static::orderBy('sort_order')->orderBy('id')->get();
        $result = [];
        static::buildFlatList($all, null, 0, $result, $excludeId);
        return $result;
    }

    private static function buildFlatList($all, $parentId, int $depth, array &$result, ?int $excludeId): void
    {
        foreach ($all->filter(fn($item) => $item->parent_id === $parentId) as $item) {
            if ($item->id === $excludeId) {
                continue;
            }
            $result[] = ['item' => $item, 'depth' => $depth];
            static::buildFlatList($all, $item->id, $depth + 1, $result, $excludeId);
        }
    }

    public static function generateSlug(string $name, ?int $excludeId = null): string
    {
        $base = str_replace(' ', '-', trim($name));
        $slug = $base;
        $counter = 1;

        while (
            static::where('slug', $slug)
                ->when($excludeId, fn($q) => $q->where('id', '!=', $excludeId))
                ->exists()
        ) {
            $slug = $base . '-' . $counter++;
        }

        return $slug;
    }
}
