<?php

declare(strict_types=1);

use App\Models\Plan;
use App\Models\PlanPrice;

it('has prices relationship', function () {
    $plan = Plan::factory()->create();

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'monthly',
        'price' => 5.00,
    ]);

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'annual',
        'price' => 51.00,
    ]);

    expect($plan->prices)->toHaveCount(2);
    expect($plan->prices->first())->toBeInstanceOf(PlanPrice::class);
});

it('resolves price for cycle', function () {
    $plan = Plan::factory()->create();

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'monthly',
        'price' => 5.00,
    ]);

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'quarterly',
        'price' => 14.25,
    ]);

    $monthly = $plan->priceForCycle('monthly');
    expect($monthly)->not->toBeNull();
    expect((float) $monthly->price)->toBe(5.00);

    $quarterly = $plan->priceForCycle('quarterly');
    expect((float) $quarterly->price)->toBe(14.25);

    $invalid = $plan->priceForCycle('weekly');
    expect($invalid)->toBeNull();
});

it('enforces unique plan_id and billing_cycle', function () {
    $plan = Plan::factory()->create();

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'monthly',
        'price' => 5.00,
    ]);

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'monthly',
        'price' => 6.00,
    ]);
})->throws(\Illuminate\Database\QueryException::class);

it('cascade deletes plan prices when plan is deleted', function () {
    $plan = Plan::factory()->create();

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'monthly',
        'price' => 5.00,
    ]);

    PlanPrice::create([
        'plan_id' => $plan->id,
        'billing_cycle' => 'annual',
        'price' => 51.00,
    ]);

    expect(PlanPrice::where('plan_id', $plan->id)->count())->toBe(2);

    $plan->delete();

    expect(PlanPrice::where('plan_id', $plan->id)->count())->toBe(0);
});

it('seeds all VPS plans with 4 price cycles each', function () {
    $this->seed(\Database\Seeders\PlanSeeder::class);

    $vpsSlugs = ['vps-1', 'vps-2', 'vps-4', 'vps-8', 'vps-16', 'vps-32', 'stor-500', 'stor-1tb'];

    foreach ($vpsSlugs as $slug) {
        $plan = Plan::where('slug', $slug)->first();
        expect($plan)->not->toBeNull("Plan {$slug} should exist");
        expect($plan->status)->toBe('active');
        expect($plan->prices)->toHaveCount(4, "Plan {$slug} should have 4 price cycles");

        $cycles = $plan->prices->pluck('billing_cycle')->sort()->values()->toArray();
        expect($cycles)->toBe(['annual', 'monthly', 'quarterly', 'semi_annual']);
    }
});

it('archives old VPS plan slugs', function () {
    Plan::factory()->create(['slug' => 'vps-nano', 'service_type' => 'vps', 'status' => 'active']);

    $this->seed(\Database\Seeders\PlanSeeder::class);

    $oldPlan = Plan::where('slug', 'vps-nano')->first();
    expect($oldPlan->status)->toBe('inactive');
});

it('sets correct monthly base prices', function () {
    $this->seed(\Database\Seeders\PlanSeeder::class);

    $expectedPrices = [
        'vps-1' => 5.00,
        'vps-2' => 8.00,
        'vps-4' => 15.00,
        'vps-8' => 30.00,
        'vps-16' => 55.00,
        'vps-32' => 99.00,
        'stor-500' => 18.00,
        'stor-1tb' => 28.00,
    ];

    foreach ($expectedPrices as $slug => $expectedPrice) {
        $plan = Plan::where('slug', $slug)->first();
        expect((float) $plan->price)->toBe($expectedPrice, "Plan {$slug} monthly price mismatch");
        expect((float) $plan->priceForCycle('monthly')->price)->toBe($expectedPrice);
    }
});
