<?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('client_integrations', function (Blueprint $table): void {
            $table->id();
            $table->foreignId('client_id')->constrained('clients')->cascadeOnDelete();
            $table->string('integration_code');
            $table->longText('integration_data')->nullable();
            $table->timestamps();

            $table->foreign('integration_code')
                ->references('integration_code')
                ->on('integrations')
                ->cascadeOnDelete();
            $table->unique(['client_id', 'integration_code']);
        });

        DB::table('tenant_integration')
            ->join('tenants', 'tenants.codigo', '=', 'tenant_integration.tenant_code')
            ->select([
                'tenants.client_id',
                'tenant_integration.integration_code',
                'tenant_integration.integration_data',
                'tenant_integration.created_at',
                'tenant_integration.updated_at',
            ])
            ->orderBy('tenant_integration.id')
            ->each(function (object $configuration): void {
                DB::table('client_integrations')->updateOrInsert(
                    [
                        'client_id' => $configuration->client_id,
                        'integration_code' => $configuration->integration_code,
                    ],
                    [
                        'integration_data' => $configuration->integration_data,
                        'created_at' => $configuration->created_at,
                        'updated_at' => $configuration->updated_at,
                    ],
                );
            });

        Schema::table('integrations', function (Blueprint $table): void {
            $table->boolean('requires_client_configuration')->default(true);
        });

        DB::table('integrations')->update([
            'requires_client_configuration' => DB::raw('requires_tenant_configuration'),
        ]);

        Schema::table('integrations', function (Blueprint $table): void {
            $table->dropColumn('requires_tenant_configuration');
        });

        Schema::dropIfExists('tenant_integration');
    }

    public function down(): void
    {
        Schema::table('integrations', function (Blueprint $table): void {
            $table->boolean('requires_tenant_configuration')->default(true);
        });

        DB::table('integrations')->update([
            'requires_tenant_configuration' => DB::raw('requires_client_configuration'),
        ]);

        Schema::table('integrations', function (Blueprint $table): void {
            $table->dropColumn('requires_client_configuration');
        });

        Schema::create('tenant_integration', function (Blueprint $table): void {
            $table->id();
            $table->string('integration_code');
            $table->string('tenant_code');
            $table->longText('integration_data')->nullable();
            $table->timestamps();

            $table->foreign('integration_code')->references('integration_code')->on('integrations')->cascadeOnDelete();
            $table->foreign('tenant_code')->references('codigo')->on('tenants')->cascadeOnDelete();
            $table->unique(['integration_code', 'tenant_code']);
        });

        DB::table('client_integrations')
            ->join('tenants', 'tenants.client_id', '=', 'client_integrations.client_id')
            ->select([
                'tenants.codigo as tenant_code',
                'client_integrations.integration_code',
                'client_integrations.integration_data',
                'client_integrations.created_at',
                'client_integrations.updated_at',
            ])
            ->orderBy('client_integrations.id')
            ->each(function (object $configuration): void {
                DB::table('tenant_integration')->insert((array) $configuration);
            });

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