<?php

declare(strict_types=1);

use App\Models\Plan;
use App\Models\PlanConfigGroup;
use Database\Seeders\ConfigOptionSeeder;
use Database\Seeders\PlanSeeder;
use Database\Seeders\RoleAndPermissionSeeder;

beforeEach(function (): void {
    $this->seed(RoleAndPermissionSeeder::class);
    $this->seed(PlanSeeder::class);
    $this->seed(ConfigOptionSeeder::class);
});

test('vps-hosting page loads with all estimator props', function (): void {
    $response = $this->get('/vps-hosting');

    $response->assertOk();

    $page = $response->viewData('page');
    expect($page['component'])->toBe('Marketing/VpsHosting');
    expect($page['props'])->toHaveKeys(['plans', 'addOns', 'workloadMap', 'appExamples']);
});

test('vps-hosting workloadMap includes all 9 workload keys', function (): void {
    $response = $this->get('/vps-hosting');
    $page = $response->viewData('page');
    $workloadMap = $page['props']['workloadMap'];

    expect(array_keys($workloadMap))->toEqualCanonicalizing([
        'personal_site', 'saas', 'dev_staging', 'discord_bot', 'vpn',
        'storage_target', 'database', 'cicd', 'not_sure',
    ]);
});

test('vps-hosting appExamples list has 12 entries with the Other escape hatch', function (): void {
    $response = $this->get('/vps-hosting');
    $page = $response->viewData('page');
    $apps = $page['props']['appExamples'];

    expect($apps)->toHaveCount(12);
    $keys = array_column($apps, 'key');
    expect($keys)->toContain('other');
    // Plans referenced in the catalog must exist
    foreach ($apps as $app) {
        if ($app['plan'] !== null) {
            expect(Plan::where('slug', $app['plan'])->exists())->toBeTrue("Plan {$app['plan']} missing");
        }
    }
});

test('seeder creates VPS Managed Support group with 4 tier values', function (): void {
    $group = PlanConfigGroup::where('name', 'VPS Managed Support')->first();
    expect($group)->not->toBeNull();
    expect($group->service_type)->toBe('vps');

    $option = $group->options->firstWhere('name', 'Managed Support');
    expect($option)->not->toBeNull();

    $values = $option->values->pluck('value')->all();
    expect($values)->toEqualCanonicalizing(['self', 'basic', 'pro', 'pilot']);
});

test('seeder creates Off-site Backup group with 5 tier values', function (): void {
    $group = PlanConfigGroup::where('name', 'Off-site Backup')->first();
    expect($group)->not->toBeNull();
    expect($group->service_type)->toBe('vps');

    $option = $group->options->firstWhere('name', 'Backup Tier');
    $values = $option->values->pluck('value')->all();

    expect($values)->toEqualCanonicalizing(['none', 'lite', 'standard', 'extended', 'vault']);
});

test('VPS plans expose a tier feature for Pilot gating', function (): void {
    $vps8 = Plan::where('slug', 'vps-8')->first();
    expect($vps8->features['tier'] ?? null)->toBe(8);

    $vps1 = Plan::where('slug', 'vps-1')->first();
    expect($vps1->features['tier'] ?? null)->toBe(1);

    $stor1tb = Plan::where('slug', 'stor-1tb')->first();
    expect($stor1tb->features['tier'] ?? null)->toBe(4);
});

test('Server Management group is scoped to dedicated only after the seeder runs', function (): void {
    $group = PlanConfigGroup::where('name', 'Server Management')->first();
    expect($group->service_type)->toBe('dedicated');
});

test('VPS plans have the new managed and backup groups attached', function (): void {
    $vps4 = Plan::where('slug', 'vps-4')->first();
    $groupNames = $vps4->configGroups->pluck('name')->all();

    expect($groupNames)->toContain('VPS Managed Support');
    expect($groupNames)->toContain('Off-site Backup');
    expect($groupNames)->toContain('VPS Add-ons');
});

test('checkout pre-fill pulls managed and backup tiers from query params', function (): void {
    $user = \App\Models\User::factory()->create();
    $user->assignRole('customer');

    $vps8 = Plan::where('slug', 'vps-8')->first();

    $accountUrl = 'http://'.config('app.domains.account');

    $response = $this->actingAs($user)
        ->get("{$accountUrl}/checkout/{$vps8->id}?managed=pilot&backup=standard&ipv4=3");

    $response->assertOk();
    $page = $response->viewData('page');
    $prefilled = $page['props']['prefilledSelections'] ?? [];

    expect($prefilled)->toBeArray();
    expect(count($prefilled))->toBeGreaterThanOrEqual(3);

    // Find the managed support entry
    $managedGroup = PlanConfigGroup::where('name', 'VPS Managed Support')->first();
    $managedOption = $managedGroup->options->firstWhere('name', 'Managed Support');
    $pilotValue = $managedOption->values->firstWhere('value', 'pilot');

    $managedSelection = collect($prefilled)->firstWhere('option_id', $managedOption->id);
    expect($managedSelection)->not->toBeNull();
    expect($managedSelection['value_id'])->toBe($pilotValue->id);

    // Find the backup entry
    $backupGroup = PlanConfigGroup::where('name', 'Off-site Backup')->first();
    $backupOption = $backupGroup->options->firstWhere('name', 'Backup Tier');
    $standardValue = $backupOption->values->firstWhere('value', 'standard');

    $backupSelection = collect($prefilled)->firstWhere('option_id', $backupOption->id);
    expect($backupSelection['value_id'])->toBe($standardValue->id);

    // IPv4 — total of 3 should produce 2 extras
    $ipv4Group = PlanConfigGroup::where('name', 'VPS Add-ons')->first();
    $ipv4Option = $ipv4Group->options->firstWhere('name', 'IPv4 Addresses');
    $ipv4Selection = collect($prefilled)->firstWhere('option_id', $ipv4Option->id);
    expect($ipv4Selection['quantity'])->toBe(2);
});

test('checkout pre-fill skips defaults when no params present', function (): void {
    $user = \App\Models\User::factory()->create();
    $user->assignRole('customer');

    $vps4 = Plan::where('slug', 'vps-4')->first();

    $accountUrl = 'http://'.config('app.domains.account');
    $response = $this->actingAs($user)->get("{$accountUrl}/checkout/{$vps4->id}");
    $response->assertOk();
    $page = $response->viewData('page');

    expect($page['props']['prefilledSelections'])->toBe([]);
});
