<?php

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

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        $driver = DB::getDriverName();

        if ($driver === 'sqlite') {
            return;
        }

        if (! Schema::hasColumn('managed_environments', 'workspace_id')) {
            return;
        }

        DB::transaction(function (): void {
            $tenantIds = DB::table('managed_environments')->whereNull('workspace_id')->pluck('id');

            foreach ($tenantIds as $tenantId) {
                $workspaceId = DB::table('managed_environment_memberships')
                    ->join('workspace_memberships', 'workspace_memberships.user_id', '=', 'managed_environment_memberships.user_id')
                    ->where('managed_environment_memberships.managed_environment_id', $tenantId)
                    ->orderByRaw("CASE managed_environment_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END")
                    ->value('workspace_memberships.workspace_id');

                if ($workspaceId !== null) {
                    DB::table('managed_environments')
                        ->where('id', $tenantId)
                        ->update(['workspace_id' => (int) $workspaceId]);
                }
            }

            $remaining = (int) DB::table('managed_environments')->whereNull('workspace_id')->count();

            if ($remaining === 0) {
                return;
            }

            $legacyWorkspaceId = DB::table('workspaces')->insertGetId([
                'name' => 'Legacy Workspace',
                'slug' => 'legacy',
                'created_at' => now(),
                'updated_at' => now(),
            ]);

            $users = DB::table('managed_environment_memberships')
                ->join('managed_environments', 'managed_environments.id', '=', 'managed_environment_memberships.managed_environment_id')
                ->whereNull('managed_environments.workspace_id')
                ->select([
                    'managed_environment_memberships.user_id',
                    DB::raw("MIN(CASE managed_environment_memberships.role WHEN 'owner' THEN 0 WHEN 'manager' THEN 1 WHEN 'operator' THEN 2 ELSE 3 END) AS role_rank"),
                ])
                ->groupBy('managed_environment_memberships.user_id')
                ->get();

            $roleFromRank = static fn (int $rank): string => match ($rank) {
                0 => 'owner',
                1 => 'manager',
                2 => 'operator',
                default => 'readonly',
            };

            $membershipRows = [];

            foreach ($users as $user) {
                $membershipRows[] = [
                    'workspace_id' => (int) $legacyWorkspaceId,
                    'user_id' => (int) $user->user_id,
                    'role' => $roleFromRank((int) $user->role_rank),
                    'created_at' => now(),
                    'updated_at' => now(),
                ];
            }

            if ($membershipRows !== []) {
                DB::table('workspace_memberships')->insertOrIgnore($membershipRows);
            }

            DB::table('managed_environments')
                ->whereNull('workspace_id')
                ->update(['workspace_id' => (int) $legacyWorkspaceId]);
        });

        if ($driver === 'pgsql') {
            DB::statement('ALTER TABLE managed_environments ALTER COLUMN workspace_id SET NOT NULL');

            return;
        }

        if ($driver === 'mysql') {
            DB::statement('ALTER TABLE managed_environments MODIFY workspace_id BIGINT UNSIGNED NOT NULL');
        }
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        $driver = DB::getDriverName();

        if ($driver === 'sqlite') {
            return;
        }

        if (! Schema::hasColumn('managed_environments', 'workspace_id')) {
            return;
        }

        if ($driver === 'pgsql') {
            DB::statement('ALTER TABLE managed_environments ALTER COLUMN workspace_id DROP NOT NULL');

            return;
        }

        if ($driver === 'mysql') {
            DB::statement('ALTER TABLE managed_environments MODIFY workspace_id BIGINT UNSIGNED NULL');
        }
    }
};
