<?php

namespace Tests\Feature;

use App\Exceptions\Vtu\NoVendorRouteException;
use App\Models\Category;
use App\Models\Network;
use App\Models\Plan;
use App\Models\PlanVendorMapping;
use App\Models\ServiceVendorMapping;
use App\Models\Vendor;
use App\Services\VendorRouter;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class VendorRouterDataPlanCodeGuardTest extends TestCase
{
    use RefreshDatabase;

    public function test_data_router_skips_service_vendor_without_plan_code(): void
    {
        $category = Category::create(['name' => 'Data SME', 'slug' => 'data_sme']);
        $network = Network::create(['name' => 'MTN', 'slug' => 'mtn']);
        $plan = Plan::create([
            'network_id' => $network->id,
            'category_id' => $category->id,
            'name' => 'MTN SME 500MB',
            'value' => '500MB',
            'selling_price' => 400,
            'status' => 'available',
            'sort_order' => 1,
        ]);

        $vendorWithCode = Vendor::create([
            'name' => 'Vendor With Code',
            'type' => 'msorg',
            'base_url' => 'https://with-code.example.com',
            'auth_type' => 'token',
            'secret_encrypted' => 'secret-a',
            'status' => 'active',
            'timeout_seconds' => 30,
        ]);

        $vendorWithoutCode = Vendor::create([
            'name' => 'Vendor Without Code',
            'type' => 'msorg',
            'base_url' => 'https://without-code.example.com',
            'auth_type' => 'token',
            'secret_encrypted' => 'secret-b',
            'status' => 'active',
            'timeout_seconds' => 30,
        ]);

        ServiceVendorMapping::create([
            'category_id' => $category->id,
            'network_id' => $network->id,
            'vendor_id' => $vendorWithCode->id,
            'priority' => 1,
            'status' => 'active',
            'force_vendor' => false,
        ]);

        ServiceVendorMapping::create([
            'category_id' => $category->id,
            'network_id' => $network->id,
            'vendor_id' => $vendorWithoutCode->id,
            'priority' => 2,
            'status' => 'active',
            'force_vendor' => false,
        ]);

        PlanVendorMapping::create([
            'plan_id' => $plan->id,
            'vendor_id' => $vendorWithCode->id,
            'vendor_plan_code' => '599',
            'priority' => 1,
            'status' => 'active',
            'force_vendor' => false,
        ]);

        $router = app(VendorRouter::class);
        $candidates = $router->resolveCandidates($plan, $category, $network);

        $this->assertCount(1, $candidates);
        $this->assertSame($vendorWithCode->id, (int) $candidates->first()['vendor']->id);
        $this->assertSame('599', (string) $candidates->first()['vendor_plan_code']);
    }

    public function test_data_router_throws_when_no_vendor_has_plan_code(): void
    {
        $category = Category::create(['name' => 'Data SME', 'slug' => 'data_sme']);
        $network = Network::create(['name' => 'MTN', 'slug' => 'mtn']);
        $plan = Plan::create([
            'network_id' => $network->id,
            'category_id' => $category->id,
            'name' => 'MTN SME 1GB',
            'value' => '1GB',
            'selling_price' => 500,
            'status' => 'available',
            'sort_order' => 2,
        ]);

        $vendor = Vendor::create([
            'name' => 'Vendor Missing Code',
            'type' => 'msorg',
            'base_url' => 'https://missing-code.example.com',
            'auth_type' => 'token',
            'secret_encrypted' => 'secret-c',
            'status' => 'active',
            'timeout_seconds' => 30,
        ]);

        ServiceVendorMapping::create([
            'category_id' => $category->id,
            'network_id' => $network->id,
            'vendor_id' => $vendor->id,
            'priority' => 1,
            'status' => 'active',
            'force_vendor' => false,
        ]);

        $router = app(VendorRouter::class);

        $this->expectException(NoVendorRouteException::class);
        $this->expectExceptionMessage('No active vendor mapping found for this service/plan.');

        $router->resolveCandidates($plan, $category, $network);
    }
}

