<?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('dedicated-servers landing page returns all 14th-gen + legacy plans', function (): void {
    $response = $this->get('/dedicated-servers');
    $response->assertOk();

    $page = $response->viewData('page');
    expect($page['component'])->toBe('Marketing/DedicatedServers');

    $plans = collect($page['props']['plans']);
    expect($plans)->toHaveCount(16);

    // 8 14th-gen build-to-order
    $buildToOrder = $plans->where('features.generation', '14th-gen');
    expect($buildToOrder)->toHaveCount(8);

    // 8 legacy 12th/13th-gen in-stock
    $legacy = $plans->whereIn('features.generation', ['12th-gen', '13th-gen']);
    expect($legacy)->toHaveCount(8);
});

test('all 8 14th-gen chassis have setup_fee in the expected tier band', function (): void {
    $expected = [
        'r440-4lff' => 149,
        'r540-8lff' => 249,
        'r640-8sff' => 149,
        'r740-16sff' => 249,
        'r740xd-24sff' => 249,
        'r740xd-12lff' => 249,
        'r640-10nvme' => 399,
        'r740xd-24nvme' => 399,
    ];

    foreach ($expected as $slug => $fee) {
        $plan = Plan::where('slug', $slug)->first();
        expect($plan)->not->toBeNull("Plan $slug missing");
        expect((float) $plan->setup_fee)->toBe((float) $fee);
        expect($plan->status)->toBe('active');
    }
});

test('legacy 12th/13th-gen plans are active with zero setup fee', function (): void {
    $legacySlugs = [
        'dell-r330-lff', 'dell-r420-lff', 'dell-r620-sff-10-bay',
        'dell-r620-sff-8-bay', 'dell-r520-lff', 'dell-r430-lff',
        'dell-r630-sff', 'dell-r730-lff',
    ];

    foreach ($legacySlugs as $slug) {
        $plan = Plan::where('slug', $slug)->first();
        expect($plan)->not->toBeNull();
        expect($plan->status)->toBe('active');
        expect((float) $plan->setup_fee)->toBe(0.0);
    }
});

test('per-chassis detail page renders for every 14th-gen slug', function (): void {
    $slugs = [
        'r440-4lff', 'r540-8lff', 'r640-8sff', 'r740-16sff',
        'r740xd-24sff', 'r740xd-12lff', 'r640-10nvme', 'r740xd-24nvme',
    ];

    foreach ($slugs as $slug) {
        $response = $this->get("/dedicated-servers/{$slug}");
        $response->assertOk();
        $page = $response->viewData('page');
        expect($page['component'])->toBe('Marketing/DedicatedServerDetail');
        expect($page['props']['plan']['slug'])->toBe($slug);
    }
});

test('detail page returns 404 for invalid slug', function (): void {
    $this->get('/dedicated-servers/does-not-exist')->assertNotFound();
});

test('detail page exposes chassis-specific config groups', function (): void {
    $response = $this->get('/dedicated-servers/r740xd-24nvme');
    $response->assertOk();

    $configGroups = collect($response->viewData('page')['props']['configGroups']);
    $names = $configGroups->pluck('name');

    // R740xd variants get the R740xd CPU group, not the standard CPU group
    expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade (R740xd)');
    expect($names)->not->toContain('Dedicated 14th Gen — CPU Upgrade');

    // Universal groups (RAM, OS, Bandwidth, IPv4) attach to all 8 chassis
    expect($names)->toContain('Dedicated 14th Gen — RAM Upgrade');
    expect($names)->toContain('Dedicated 14th Gen — Operating System');
    expect($names)->toContain('Dedicated 14th Gen — Bandwidth');
    expect($names)->toContain('Dedicated 14th Gen — IPv4 Block');
});

test('non-R740xd chassis get the standard CPU group', function (): void {
    $response = $this->get('/dedicated-servers/r440-4lff');
    $response->assertOk();

    $names = collect($response->viewData('page')['props']['configGroups'])->pluck('name');

    expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade');
    expect($names)->not->toContain('Dedicated 14th Gen — CPU Upgrade (R740xd)');
});

test('seeder creates the 9 dedicated 14th-gen config groups', function (): void {
    $names = PlanConfigGroup::query()
        ->where('name', 'like', 'Dedicated 14th Gen%')
        ->pluck('name')
        ->all();

    expect(count($names))->toBe(9);
    expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade');
    expect($names)->toContain('Dedicated 14th Gen — CPU Upgrade (R740xd)');
    expect($names)->toContain('Dedicated 14th Gen — RAM Upgrade');
    expect($names)->toContain('Dedicated 14th Gen — Operating System');
    expect($names)->toContain('Dedicated 14th Gen — Bandwidth');
    expect($names)->toContain('Dedicated 14th Gen — IPv4 Block');
    expect($names)->toContain('Dedicated 14th Gen — LFF Drive Bays');
    expect($names)->toContain('Dedicated 14th Gen — SFF Drive Bays');
    expect($names)->toContain('Dedicated 14th Gen — NVMe Drive Bays');
});

test('drive bay options are filtered to those that fit chassis bay count', function (): void {
    // R440 has 4 LFF bays — combos requiring more bays should be hidden.
    $r440Response = $this->get('/dedicated-servers/r440-4lff');
    $r440Groups = collect($r440Response->viewData('page')['props']['configGroups']);
    $lff = $r440Groups->firstWhere('name', 'Dedicated 14th Gen — LFF Drive Bays');
    $values = collect($lff['options'][0]['values'])->pluck('value')->all();
    expect($values)->toContain('none', '2x4tb-hdd', '4x4tb-hdd', '2x8tb-hdd', '4x8tb-hdd');
    expect($values)->not->toContain('8x8tb-hdd', '12x8tb-hdd'); // 8 and 12 bays don't fit in 4

    // R740xd LFF has 12 bays — should see all combos.
    $r740xdResponse = $this->get('/dedicated-servers/r740xd-12lff');
    $r740xdGroups = collect($r740xdResponse->viewData('page')['props']['configGroups']);
    $lff740 = $r740xdGroups->firstWhere('name', 'Dedicated 14th Gen — LFF Drive Bays');
    $values740 = collect($lff740['options'][0]['values'])->pluck('value')->all();
    expect($values740)->toContain('8x8tb-hdd', '12x8tb-hdd');

    // R640 NVMe has 10 bays — 16× shouldn't fit but 8× should.
    $r640Response = $this->get('/dedicated-servers/r640-10nvme');
    $r640Groups = collect($r640Response->viewData('page')['props']['configGroups']);
    $nvme = $r640Groups->firstWhere('name', 'Dedicated 14th Gen — NVMe Drive Bays');
    $valuesNvme = collect($nvme['options'][0]['values'])->pluck('value')->all();
    expect($valuesNvme)->toContain('8x2tb-nvme');
    expect($valuesNvme)->not->toContain('16x2tb-nvme'); // 16 bays don't fit in 10
});

test('drive bay groups are attached to chassis by bay type', function (): void {
    // LFF chassis should have LFF Drive Bays attached
    $r440 = Plan::where('slug', 'r440-4lff')->first();
    expect($r440->configGroups->pluck('name'))->toContain('Dedicated 14th Gen — LFF Drive Bays');
    expect($r440->configGroups->pluck('name'))->not->toContain('Dedicated 14th Gen — SFF Drive Bays');
    expect($r440->configGroups->pluck('name'))->not->toContain('Dedicated 14th Gen — NVMe Drive Bays');

    // SFF chassis should have SFF Drive Bays
    $r640 = Plan::where('slug', 'r640-8sff')->first();
    expect($r640->configGroups->pluck('name'))->toContain('Dedicated 14th Gen — SFF Drive Bays');
    expect($r640->configGroups->pluck('name'))->not->toContain('Dedicated 14th Gen — LFF Drive Bays');

    // NVMe chassis should have NVMe Drive Bays
    $nvme = Plan::where('slug', 'r740xd-24nvme')->first();
    expect($nvme->configGroups->pluck('name'))->toContain('Dedicated 14th Gen — NVMe Drive Bays');
    expect($nvme->configGroups->pluck('name'))->not->toContain('Dedicated 14th Gen — SFF Drive Bays');
});

test('RAM upgrade group standardizes on DDR4-2400 across all tiers', function (): void {
    $group = PlanConfigGroup::where('name', 'Dedicated 14th Gen — RAM Upgrade')->first();
    $values = $group->options->first()->values;

    expect($values)->toHaveCount(7);
    foreach ($values as $value) {
        expect($value->label)->toContain('DDR4-2400');
    }
});

test('checkout setupFee prop is exposed on dedicated plan checkout', function (): void {
    $user = \App\Models\User::factory()->create();
    $user->assignRole('customer');

    $r440 = Plan::where('slug', 'r440-4lff')->first();
    $accountUrl = 'http://'.config('app.domains.account');

    $response = $this->actingAs($user)->get("{$accountUrl}/checkout/{$r440->id}");
    $response->assertOk();

    expect($response->viewData('page')['props']['setupFee'])->toBe(149.0);
});

test('checkout setupFee on a VPS plan is zero', function (): void {
    $user = \App\Models\User::factory()->create();
    $user->assignRole('customer');

    $vps = Plan::where('slug', 'vps-1')->first();
    $accountUrl = 'http://'.config('app.domains.account');

    $response = $this->actingAs($user)->get("{$accountUrl}/checkout/{$vps->id}");
    $response->assertOk();

    expect($response->viewData('page')['props']['setupFee'])->toBe(0.0);
});
