<?php

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

return new class extends Migration
{
    public function up(): void
    {
        $groupsById = DB::table('mariachi_groups')
            ->select(['id', 'code', 'name'])
            ->get()
            ->keyBy('id');

        $buildPrefix = static function (?string $code, ?string $name): string {
            $source = trim((string) ($code ?: $name));
            $normalized = (string) Str::of($source)
                ->ascii()
                ->replaceMatches('/[^A-Za-z0-9]+/', ' ')
                ->trim();

            if ($normalized === '') {
                return 'SR';
            }

            $segments = preg_split('/\s+/', $normalized, -1, PREG_SPLIT_NO_EMPTY) ?: [];
            $prefix = '';

            foreach ($segments as $segment) {
                if (ctype_digit($segment)) {
                    $prefix .= $segment;
                    continue;
                }

                $prefix .= Str::upper(Str::substr($segment, 0, 1));
            }

            if ($prefix === '') {
                $prefix = Str::upper(Str::substr(str_replace(' ', '', $normalized), 0, 3));
            }

            return (string) Str::of($prefix)->upper()->substr(0, 8);
        };

        DB::table('serenatas')
            ->select(['id', 'mariachi_group_id', 'sequence'])
            ->orderBy('id')
            ->chunkById(200, function ($serenatas) use ($groupsById, $buildPrefix) {
                foreach ($serenatas as $serenata) {
                    $group = $groupsById->get($serenata->mariachi_group_id);
                    $prefix = $buildPrefix($group->code ?? null, $group->name ?? null);
                    $sequence = max(1, (int) $serenata->sequence);

                    DB::table('serenatas')
                        ->where('id', $serenata->id)
                        ->update([
                            'code' => $prefix . '-' . $sequence,
                            'updated_at' => now(),
                        ]);
                }
            });
    }

    public function down(): void
    {
        // No reversible: los códigos anteriores no se conservan.
    }
};
