<?php

use App\Domains\Menu\Models\Menu;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;

return new class extends Migration
{
    public function up(): void
    {
        $now = now();

        DB::table('menues')->updateOrInsert(
            ['code' => 'account'],
            [
                'parent_menu_code' => null,
                'content_type' => Menu::CONTENT_TYPE_DYNAMIC,
                'static_content_schema' => null,
                'route' => '/mi-cuenta',
                'created_at' => $now,
                'updated_at' => $now,
            ]
        );

        $menus = [
            'profile' => [
                'code' => 'account.profile',
                'route' => '/mi-cuenta/datos-personales',
            ],
            'purchases' => [
                'code' => 'account.purchases',
                'route' => '/mi-cuenta/compras',
            ],
            'tickets' => [
                'code' => 'account.tickets',
                'route' => '/mi-cuenta/tickets',
            ],
        ];

        foreach ($menus as $legacyCode => $menuData) {
            $legacyMenu = DB::table('menues')->where('code', $legacyCode)->first();

            DB::table('menues')->updateOrInsert(
                ['code' => $menuData['code']],
                [
                    'parent_menu_code' => 'account',
                    'content_type' => $legacyMenu?->content_type ?? Menu::CONTENT_TYPE_DYNAMIC,
                    'static_content_schema' => $legacyMenu?->static_content_schema,
                    'route' => $menuData['route'],
                    'created_at' => $legacyMenu?->created_at ?? $now,
                    'updated_at' => $now,
                ]
            );

            if (! $legacyMenu) {
                continue;
            }

            $assignments = DB::table('tenants_menues')
                ->where('menu_code', $legacyCode)
                ->get();

            foreach ($assignments as $assignment) {
                $alreadyAssigned = DB::table('tenants_menues')
                    ->where('tenant_code', $assignment->tenant_code)
                    ->where('menu_code', $menuData['code'])
                    ->exists();

                if (! $alreadyAssigned) {
                    DB::table('tenants_menues')->insert([
                        'tenant_code' => $assignment->tenant_code,
                        'menu_code' => $menuData['code'],
                        'static_content' => $assignment->static_content,
                        'created_at' => $assignment->created_at,
                        'updated_at' => $now,
                    ]);
                }
            }

            DB::table('tenants_menues')->where('menu_code', $legacyCode)->delete();
            DB::table('menues')->where('code', $legacyCode)->delete();
        }

        $tenantCodes = DB::table('tenants_menues')
            ->whereIn('menu_code', array_column($menus, 'code'))
            ->distinct()
            ->pluck('tenant_code');

        foreach ($tenantCodes as $tenantCode) {
            $alreadyAssigned = DB::table('tenants_menues')
                ->where('tenant_code', $tenantCode)
                ->where('menu_code', 'account')
                ->exists();

            if ($alreadyAssigned) {
                continue;
            }

            DB::table('tenants_menues')->insert([
                'tenant_code' => $tenantCode,
                'menu_code' => 'account',
                'static_content' => null,
                'created_at' => $now,
                'updated_at' => $now,
            ]);
        }
    }

    public function down(): void
    {
        $now = now();
        $menus = [
            'account.profile' => [
                'code' => 'profile',
                'route' => '/profile',
            ],
            'account.purchases' => [
                'code' => 'purchases',
                'route' => '/purchases',
            ],
            'account.tickets' => [
                'code' => 'tickets',
                'route' => '/tickets',
            ],
        ];

        foreach ($menus as $accountCode => $menuData) {
            $accountMenu = DB::table('menues')->where('code', $accountCode)->first();

            DB::table('menues')->updateOrInsert(
                ['code' => $menuData['code']],
                [
                    'parent_menu_code' => null,
                    'content_type' => $accountMenu?->content_type ?? Menu::CONTENT_TYPE_DYNAMIC,
                    'static_content_schema' => $accountMenu?->static_content_schema,
                    'route' => $menuData['route'],
                    'created_at' => $accountMenu?->created_at ?? $now,
                    'updated_at' => $now,
                ]
            );

            if (! $accountMenu) {
                continue;
            }

            $assignments = DB::table('tenants_menues')
                ->where('menu_code', $accountCode)
                ->get();

            foreach ($assignments as $assignment) {
                $alreadyAssigned = DB::table('tenants_menues')
                    ->where('tenant_code', $assignment->tenant_code)
                    ->where('menu_code', $menuData['code'])
                    ->exists();

                if (! $alreadyAssigned) {
                    DB::table('tenants_menues')->insert([
                        'tenant_code' => $assignment->tenant_code,
                        'menu_code' => $menuData['code'],
                        'static_content' => $assignment->static_content,
                        'created_at' => $assignment->created_at,
                        'updated_at' => $now,
                    ]);
                }
            }

            DB::table('tenants_menues')->where('menu_code', $accountCode)->delete();
            DB::table('menues')->where('code', $accountCode)->delete();
        }

        DB::table('tenants_menues')->where('menu_code', 'account')->delete();
        DB::table('menues')->where('code', 'account')->delete();
    }
};
