<?php

namespace Tests\Feature;

use App\Models\Category;
use App\Models\Network;
use App\Models\Plan;
use App\Models\PlanVendorMapping;
use App\Models\ServiceAvailabilityRule;
use App\Models\ServiceProvider;
use App\Models\User;
use App\Models\Vendor;
use App\Services\ServiceAvailabilityService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PurchasePageVisibilityTest extends TestCase
{
    use RefreshDatabase;

    public function test_data_page_hides_disabled_data_type_plans_for_selected_network(): void
    {
        $user = User::factory()->create();
        $network = Network::query()->create([
            'name' => 'MTN',
            'slug' => 'mtn',
            'vendor_network_code_json' => ['msorg' => ['data' => '1']],
        ]);
        $categorySme = Category::query()->create(['name' => 'Data SME', 'slug' => 'data_sme']);
        $categoryGifting = Category::query()->create(['name' => 'Data Gifting', 'slug' => 'data_gifting']);

        $vendor = Vendor::query()->create([
            'name' => 'Visible Vendor',
            'type' => 'msorg',
            'base_url' => 'https://vendor.test',
            'auth_type' => 'token',
            'secret_encrypted' => 'token',
            'status' => 'active',
            'timeout_seconds' => 30,
        ]);

        $planSme = Plan::query()->create([
            'network_id' => $network->id,
            'category_id' => $categorySme->id,
            'name' => 'MTN SME 500MB',
            'value' => '500MB',
            'selling_price' => 400,
            'status' => 'available',
            'sort_order' => 1,
        ]);
        $planGifting = Plan::query()->create([
            'network_id' => $network->id,
            'category_id' => $categoryGifting->id,
            'name' => 'MTN Gifting 500MB',
            'value' => '500MB',
            'selling_price' => 450,
            'status' => 'available',
            'sort_order' => 2,
        ]);

        PlanVendorMapping::query()->create([
            'plan_id' => $planSme->id,
            'vendor_id' => $vendor->id,
            'vendor_plan_code' => 'SME-500',
            'priority' => 1,
            'status' => 'active',
        ]);
        PlanVendorMapping::query()->create([
            'plan_id' => $planGifting->id,
            'vendor_id' => $vendor->id,
            'vendor_plan_code' => 'GIFT-500',
            'priority' => 1,
            'status' => 'active',
        ]);

        $availability = app(ServiceAvailabilityService::class);
        $scope = $availability->makeScopeLookup(
            scopeType: 'network_category',
            serviceGroup: 'data',
            categoryId: $categorySme->id,
            networkId: $network->id
        );
        ServiceAvailabilityRule::query()->create([
            ...$scope,
            'status' => 'disabled',
            'is_active' => true,
        ]);

        $response = $this->withoutMiddleware()->actingAs($user)->get(route('app.buy.data'));
        $response->assertOk();

        $page = $response->viewData('page');
        $props = (array) ($page['props'] ?? []);
        $plans = collect((array) ($props['plans'] ?? []));

        $this->assertTrue($plans->contains(fn (array $plan) => data_get($plan, 'name') === 'MTN Gifting 500MB'));
        $this->assertFalse($plans->contains(fn (array $plan) => data_get($plan, 'name') === 'MTN SME 500MB'));
    }

    public function test_airtime_page_hides_networks_marked_off_in_service_controls(): void
    {
        $user = User::factory()->create();
        $category = Category::query()->create(['name' => 'Airtime VTU', 'slug' => 'airtime_vtu']);
        $networkMtn = Network::query()->create(['name' => 'MTN', 'slug' => 'mtn']);
        $networkAirtel = Network::query()->create(['name' => 'Airtel', 'slug' => 'airtel']);

        $availability = app(ServiceAvailabilityService::class);
        $scope = $availability->makeScopeLookup(
            scopeType: 'network_service_group',
            serviceGroup: 'airtime',
            networkId: $networkMtn->id
        );
        ServiceAvailabilityRule::query()->create([
            ...$scope,
            'status' => 'disabled',
            'is_active' => true,
        ]);

        $response = $this->withoutMiddleware()->actingAs($user)->get(route('app.buy.airtime'));
        $response->assertOk();

        $page = $response->viewData('page');
        $props = (array) ($page['props'] ?? []);
        $networks = collect((array) ($props['networks'] ?? []));

        $this->assertNotNull($category);
        $this->assertTrue($networks->contains(fn (array $network) => data_get($network, 'slug') === 'airtel'));
        $this->assertFalse($networks->contains(fn (array $network) => data_get($network, 'slug') === 'mtn'));
    }

    public function test_electricity_page_hides_disabled_service_providers(): void
    {
        $user = User::factory()->create();
        Category::query()->create(['name' => 'Electricity', 'slug' => 'electricity']);

        $kedco = ServiceProvider::query()->create([
            'service_group' => 'electricity',
            'name' => 'KEDCO',
            'slug' => 'kedco',
        ]);
        ServiceProvider::query()->create([
            'service_group' => 'electricity',
            'name' => 'IKEDC',
            'slug' => 'ikejaelectric',
        ]);

        $availability = app(ServiceAvailabilityService::class);
        $scope = $availability->makeScopeLookup(
            scopeType: 'service_provider',
            serviceGroup: 'electricity',
            serviceProviderId: $kedco->id
        );
        ServiceAvailabilityRule::query()->create([
            ...$scope,
            'status' => 'disabled',
            'is_active' => true,
        ]);

        $response = $this->withoutMiddleware()->actingAs($user)->get(route('app.buy.electricity'));
        $response->assertOk();

        $page = $response->viewData('page');
        $props = (array) ($page['props'] ?? []);
        $providers = collect((array) data_get($props, 'serviceProviders.electricity', []));

        $this->assertTrue($providers->contains(fn (array $provider) => data_get($provider, 'slug') === 'ikejaelectric'));
        $this->assertFalse($providers->contains(fn (array $provider) => data_get($provider, 'slug') === 'kedco'));
    }
}

