<?php

namespace Tests\Unit;

use App\Models\Category;
use App\Models\Product;
use App\Models\Service;
use App\Models\CategoryServiceOverride;
use App\Models\ProductServiceLink;
use App\Services\ServicePriceResolver;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ServicePriceResolverTest extends TestCase
{
    use RefreshDatabase;

    private ServicePriceResolver $resolver;

    protected function setUp(): void
    {
        parent::setUp();
        $this->resolver = new ServicePriceResolver();
    }

    public function test_returns_product_level_override_when_set()
    {
        $service = Service::create([
            'name' => 'Gift Wrap',
            'slug' => 'gift-wrap',
            'default_price' => 50,
            'billing_type' => 'PER_ITEM',
        ]);

        $category = Category::create([
            'name' => 'Fish',
            'slug' => 'fish',
            'is_active' => true,
            'sort_order' => 0,
        ]);

        CategoryServiceOverride::create([
            'category_id' => $category->id,
            'service_id' => $service->id,
            'override_price' => 40,
        ]);

        $product = Product::create([
            'name' => 'Hilsa Fish',
            'slug' => 'hilsa-fish',
            'price' => 500,
            'category_id' => $category->id,
            'is_active' => true,
            'in_stock' => true,
        ]);

        ProductServiceLink::create([
            'product_id' => $product->id,
            'service_id' => $service->id,
            'override_price' => 30,
            'is_enabled' => true,
        ]);

        $price = $this->resolver->calculateServicePrice($product->id, $service->id);

        $this->assertEquals('30.00', $price);
    }

    public function test_falls_back_to_category_override_when_product_override_is_null()
    {
        $service = Service::create([
            'name' => 'Gift Wrap',
            'slug' => 'gift-wrap-2',
            'default_price' => 50,
            'billing_type' => 'PER_ITEM',
        ]);

        $category = Category::create([
            'name' => 'Meat',
            'slug' => 'meat',
            'is_active' => true,
            'sort_order' => 0,
        ]);

        CategoryServiceOverride::create([
            'category_id' => $category->id,
            'service_id' => $service->id,
            'override_price' => 35,
        ]);

        $product = Product::create([
            'name' => 'Beef',
            'slug' => 'beef',
            'price' => 600,
            'category_id' => $category->id,
            'is_active' => true,
            'in_stock' => true,
        ]);

        ProductServiceLink::create([
            'product_id' => $product->id,
            'service_id' => $service->id,
            'override_price' => null,
            'is_enabled' => true,
        ]);

        $price = $this->resolver->calculateServicePrice($product->id, $service->id);

        $this->assertEquals('35.00', $price);
    }

    public function test_falls_back_to_service_default_when_no_overrides_exist()
    {
        $service = Service::create([
            'name' => 'Extended Warranty',
            'slug' => 'extended-warranty',
            'default_price' => 99,
            'billing_type' => 'PER_ITEM',
        ]);

        $category = Category::create([
            'name' => 'Electronics',
            'slug' => 'electronics',
            'is_active' => true,
            'sort_order' => 0,
        ]);

        $product = Product::create([
            'name' => 'TV',
            'slug' => 'tv',
            'price' => 25000,
            'category_id' => $category->id,
            'is_active' => true,
            'in_stock' => true,
        ]);

        ProductServiceLink::create([
            'product_id' => $product->id,
            'service_id' => $service->id,
            'override_price' => null,
            'is_enabled' => true,
        ]);

        $price = $this->resolver->calculateServicePrice($product->id, $service->id);

        $this->assertEquals('99.00', $price);
    }

    public function test_returns_null_when_product_link_is_disabled()
    {
        $service = Service::create([
            'name' => 'Assembly',
            'slug' => 'assembly',
            'default_price' => 150,
            'billing_type' => 'PER_ITEM',
        ]);

        $category = Category::create([
            'name' => 'Furniture',
            'slug' => 'furniture',
            'is_active' => true,
            'sort_order' => 0,
        ]);

        $product = Product::create([
            'name' => 'Chair',
            'slug' => 'chair',
            'price' => 3000,
            'category_id' => $category->id,
            'is_active' => true,
            'in_stock' => true,
        ]);

        ProductServiceLink::create([
            'product_id' => $product->id,
            'service_id' => $service->id,
            'override_price' => 100,
            'is_enabled' => false,
        ]);

        $price = $this->resolver->calculateServicePrice($product->id, $service->id);

        $this->assertEquals('150.00', $price);
    }

    public function test_resolve_services_for_product_returns_only_enabled()
    {
        $service1 = Service::create([
            'name' => 'Gift Wrap',
            'slug' => 'gift-wrap-res',
            'default_price' => 50,
            'billing_type' => 'PER_ITEM',
        ]);

        $service2 = Service::create([
            'name' => 'Assembly',
            'slug' => 'assembly-res',
            'default_price' => 150,
            'billing_type' => 'PER_ITEM',
        ]);

        $category = Category::create([
            'name' => 'Test',
            'slug' => 'test',
            'is_active' => true,
            'sort_order' => 0,
        ]);

        $product = Product::create([
            'name' => 'Test Product',
            'slug' => 'test-product',
            'price' => 100,
            'category_id' => $category->id,
            'is_active' => true,
            'in_stock' => true,
        ]);

        ProductServiceLink::create([
            'product_id' => $product->id,
            'service_id' => $service1->id,
            'override_price' => null,
            'is_enabled' => true,
        ]);

        ProductServiceLink::create([
            'product_id' => $product->id,
            'service_id' => $service2->id,
            'override_price' => null,
            'is_enabled' => false,
        ]);

        $resolved = $this->resolver->resolveServicesForProduct($product->id);

        $this->assertCount(1, $resolved);
        $this->assertEquals('Gift Wrap', $resolved->first()['service']->name);
        $this->assertEquals('50.00', $resolved->first()['resolved_price']);
    }
}
