<?php

namespace Tests\Unit;

use App\Http\Resources\ValuationResource;
use Mtc\VehicleValuation\Models\VehicleValuation;
use Tests\TestCase;
use Tests\TestFeatureRepository;
use Tests\TestSettingRepository;

class ValuationResourceTest extends TestCase
{
    #[\Override]
    protected function setUp(): void
    {
        parent::setUp();

        $this->app->bind('feature-flags', TestFeatureRepository::class);
        $this->app->bind('site-settings', TestSettingRepository::class);
    }

    private function makeValuation(array $attributes = []): VehicleValuation
    {
        $valuation = new VehicleValuation();
        $valuation->forceFill(array_merge([
            'id' => 1,
            'make' => 'BMW',
            'model' => '3 Series',
            'registration' => 'FOO11BAZ',
            'mileage' => 60000,
            'derivative' => 'test',
            'fuel_type' => 'petrol',
            'body_type' => 'coupe',
            'retail_price' => 20000,
            'clean_price' => 15000,
            'average_price' => 12000,
            'below_price' => 9000,
            'valuation_id' => 'abc-123',
        ], $attributes));

        return $valuation;
    }

    private function toArray(VehicleValuation $valuation): array
    {
        return (new ValuationResource($valuation))->toArray(request());
    }

    public function testReturnsAllTiersWhenNoCondition(): void
    {
        $payload = $this->toArray($this->makeValuation(['cosmetic_condition' => null]));

        $this->assertEquals(20000, $payload['retailPrice']);
        $this->assertEquals(15000, $payload['cleanPrice']);
        $this->assertEquals(12000, $payload['averagePrice']);
        $this->assertEquals(9000, $payload['belowPrice']);
    }

    public function testReturnsOnlyCleanWhenConditionGood(): void
    {
        $payload = $this->toArray($this->makeValuation(['cosmetic_condition' => 'Good']));

        $this->assertNull($payload['retailPrice']);
        $this->assertEquals(15000, $payload['cleanPrice']);
        $this->assertNull($payload['averagePrice']);
        $this->assertNull($payload['belowPrice']);
    }

    public function testReturnsOnlyCleanWhenConditionExcellent(): void
    {
        $payload = $this->toArray($this->makeValuation(['cosmetic_condition' => 'excellent']));

        $this->assertNull($payload['retailPrice']);
        $this->assertEquals(15000, $payload['cleanPrice']);
        $this->assertNull($payload['averagePrice']);
        $this->assertNull($payload['belowPrice']);
    }

    public function testReturnsOnlyAverageWhenConditionAverage(): void
    {
        $payload = $this->toArray($this->makeValuation(['cosmetic_condition' => 'Average']));

        $this->assertNull($payload['retailPrice']);
        $this->assertNull($payload['cleanPrice']);
        $this->assertEquals(12000, $payload['averagePrice']);
        $this->assertNull($payload['belowPrice']);
    }

    public function testReturnsOnlyBelowWhenConditionPoor(): void
    {
        $payload = $this->toArray($this->makeValuation(['cosmetic_condition' => 'poor']));

        $this->assertNull($payload['retailPrice']);
        $this->assertNull($payload['cleanPrice']);
        $this->assertNull($payload['averagePrice']);
        $this->assertEquals(9000, $payload['belowPrice']);
    }

    public function testFallsBackToAllTiersWhenMatchedTierIsNull(): void
    {
        $payload = $this->toArray($this->makeValuation([
            'cosmetic_condition' => 'good',
            'clean_price' => null,
        ]));

        $this->assertEquals(20000, $payload['retailPrice']);
        $this->assertNull($payload['cleanPrice']);
        $this->assertEquals(12000, $payload['averagePrice']);
        $this->assertEquals(9000, $payload['belowPrice']);
    }

    public function testUsesAdjustedPricesWhenPresent(): void
    {
        $payload = $this->toArray($this->makeValuation([
            'cosmetic_condition' => 'good',
            'adjusted_clean_price' => 14000,
        ]));

        $this->assertEquals(14000, $payload['cleanPrice']);
        $this->assertNull($payload['retailPrice']);
        $this->assertNull($payload['averagePrice']);
        $this->assertNull($payload['belowPrice']);
    }
}
