<?php

namespace Tests\Feature;

use App\Models\Category;
use App\Models\Network;
use App\Models\Plan;
use App\Models\PlanVendorMapping;
use App\Models\Vendor;
use App\Services\Providers\ProviderResponse;
use App\Services\VendorRouter;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class VendorRouterFalloverTest extends TestCase
{
    use RefreshDatabase;

    public function test_router_falls_over_in_priority_order_on_hard_failures(): 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' => 1,
        ]);

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

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

        PlanVendorMapping::create([
            'plan_id' => $plan->id,
            'vendor_id' => $firstVendor->id,
            'vendor_plan_code' => 'A-1GB',
            'priority' => 1,
            'status' => 'active',
        ]);

        PlanVendorMapping::create([
            'plan_id' => $plan->id,
            'vendor_id' => $secondVendor->id,
            'vendor_plan_code' => 'B-1GB',
            'priority' => 2,
            'status' => 'active',
        ]);

        $router = app(VendorRouter::class);
        $attempted = [];

        $result = $router->routeAndExecute($plan, $category, function (array $candidate) use (&$attempted) {
            $attempted[] = $candidate['vendor']->name;

            if ($candidate['vendor']->name === 'Vendor A') {
                return ProviderResponse::failed('Timeout', ['error' => 'timeout'], hardFailure: true);
            }

            return ProviderResponse::success('Delivered', 'VEND-REF-2', 450);
        }, $network);

        $this->assertSame(['Vendor A', 'Vendor B'], $attempted);
        $this->assertSame('Vendor B', $result['candidate']['vendor']->name);
        $this->assertTrue($result['response']->isSuccess());
    }
}

