<?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
    {
        if (! Schema::hasTable('attachment_crops')) {
            Schema::create('attachment_crops', function (Blueprint $table): void {
                $table->id();
                $table->foreignId('attachment_id')->constrained('attachments')->cascadeOnDelete();
                $table->string('variant', 20);
                $table->json('crop_horizontal');
                $table->json('crop_vertical');
                $table->foreignId('cropped_attachment_id')
                    ->unique()
                    ->constrained('attachments')
                    ->cascadeOnDelete();
                $table->timestamps();

                $table->unique(['attachment_id', 'variant']);
            });
        }

        if (Schema::hasColumn('attachments', 'cropped_attachment_id')) {
            DB::table('attachments')
                ->whereNotNull('cropped_attachment_id')
                ->orderBy('id')
                ->chunkById(100, function ($attachments): void {
                    foreach ($attachments as $attachment) {
                        DB::table('attachment_crops')->updateOrInsert(
                            ['attachment_id' => $attachment->id, 'variant' => 'desktop'],
                            [
                                'crop_horizontal' => $attachment->crop_horizontal
                                    ?? json_encode(['start_percentage' => 0, 'end_percentage' => 100]),
                                'crop_vertical' => $attachment->crop_vertical
                                    ?? json_encode(['start_percentage' => 0, 'end_percentage' => 100]),
                                'cropped_attachment_id' => $attachment->cropped_attachment_id,
                                'created_at' => now(),
                                'updated_at' => now(),
                            ]
                        );
                    }
                });

            Schema::table('attachments', function (Blueprint $table): void {
                $table->dropForeign(['cropped_attachment_id']);
                $table->dropColumn([
                    'crop_horizontal',
                    'crop_vertical',
                    'cropped_attachment_id',
                ]);
            });
        }
    }

    public function down(): void
    {
        Schema::table('attachments', function (Blueprint $table): void {
            $table->json('crop_horizontal')->nullable()->after('size');
            $table->json('crop_vertical')->nullable()->after('crop_horizontal');
            $table->foreignId('cropped_attachment_id')
                ->nullable()
                ->unique()
                ->after('crop_vertical')
                ->constrained('attachments')
                ->nullOnDelete();
        });

        DB::table('attachment_crops')
            ->where('variant', 'desktop')
            ->orderBy('id')
            ->chunkById(100, function ($crops): void {
                foreach ($crops as $crop) {
                    DB::table('attachments')
                        ->where('id', $crop->attachment_id)
                        ->update([
                            'crop_horizontal' => $crop->crop_horizontal,
                            'crop_vertical' => $crop->crop_vertical,
                            'cropped_attachment_id' => $crop->cropped_attachment_id,
                        ]);
                }
            });

        Schema::dropIfExists('attachment_crops');
    }
};
