<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        if (!Schema::hasTable('nav_items')) {
            return;
        }

        $rows = DB::table('nav_items')
            ->select(['id', 'menu_parent_id', 'label'])
            ->whereNull('deleted_at')
            ->orderBy('menu_parent_id')
            ->orderBy('label')
            ->orderBy('id')
            ->get()
            ->groupBy(fn ($row) => $row->menu_parent_id === null ? 'root' : (string) $row->menu_parent_id);

        foreach ($rows as $siblings) {
            $ordered = $siblings->values()->all();
            usort($ordered, function ($a, $b) {
                $result = strnatcasecmp($this->labelKey((string) ($a->label ?? '')), $this->labelKey((string) ($b->label ?? '')));

                return $result !== 0 ? $result : ((int) $a->id <=> (int) $b->id);
            });

            foreach ($ordered as $index => $item) {
                DB::table('nav_items')
                    ->where('id', (int) $item->id)
                    ->update([
                        'sort_order' => ($index + 1) * 10,
                        'updated_at' => now(),
                    ]);
            }
        }
    }

    public function down(): void
    {
        // Alphabetical sort order normalization is intentionally not reversible.
    }

    private function labelKey(string $s): string
    {
        $s = trim(preg_replace('/\s+/', ' ', $s));
        $s = preg_replace('/^[^[:alnum:]]+/u', '', $s);
        $s = preg_replace('/^(?i)(the|an|a)\s+/', '', $s);

        return mb_strtolower($s, 'UTF-8');
    }
};
