<?php

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

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('ticket_validity_groups', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('ticket_id')
                ->constrained('tickets')
                ->cascadeOnUpdate()
                ->cascadeOnDelete();
        });

        Schema::create('ticket_validity_group_times', function (Blueprint $table): void {
            $table->foreignId('ticket_validity_group_id')
                ->constrained('ticket_validity_groups')
                ->cascadeOnUpdate()
                ->cascadeOnDelete();
            $table->foreignId('validity_time_id')
                ->constrained('validity_times')
                ->cascadeOnUpdate()
                ->restrictOnDelete();

            $table->primary(['ticket_validity_group_id', 'validity_time_id']);
        });

        // Every former pivot row was an OR alternative, so each one becomes
        // an independent group to preserve existing ticket behavior.
        DB::table('ticket_validity_times')
            ->orderBy('ticket_id')
            ->orderBy('validity_time_id')
            ->each(function (object $association): void {
                $groupId = DB::table('ticket_validity_groups')->insertGetId([
                    'ticket_id' => $association->ticket_id,
                ]);

                DB::table('ticket_validity_group_times')->insert([
                    'ticket_validity_group_id' => $groupId,
                    'validity_time_id' => $association->validity_time_id,
                ]);
            });

        Schema::dropIfExists('ticket_validity_times');
    }

    public function down(): void
    {
        Schema::create('ticket_validity_times', function (Blueprint $table): void {
            $table->foreignId('ticket_id')
                ->constrained('tickets')
                ->cascadeOnUpdate()
                ->cascadeOnDelete();
            $table->foreignId('validity_time_id')
                ->constrained('validity_times')
                ->cascadeOnUpdate()
                ->restrictOnDelete();

            $table->primary(['ticket_id', 'validity_time_id']);
        });

        DB::table('ticket_validity_group_times')
            ->join(
                'ticket_validity_groups',
                'ticket_validity_groups.id',
                '=',
                'ticket_validity_group_times.ticket_validity_group_id',
            )
            ->select([
                'ticket_validity_groups.ticket_id',
                'ticket_validity_group_times.validity_time_id',
            ])
            ->distinct()
            ->orderBy('ticket_validity_groups.ticket_id')
            ->each(fn (object $association) => DB::table('ticket_validity_times')->insert([
                'ticket_id' => $association->ticket_id,
                'validity_time_id' => $association->validity_time_id,
            ]));

        Schema::dropIfExists('ticket_validity_group_times');
        Schema::dropIfExists('ticket_validity_groups');
    }
};
