<?php

namespace Tests\Feature;

use App\Facades\Settings;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Http;
use Mtc\MercuryDataModels\Vehicle;
use Mtc\MercuryDataModels\VehicleValuation;
use Tests\DatabaseTestCase;
use Tests\UserForTenant;

class ValuationControllerTest extends DatabaseTestCase
{
    use UserForTenant;


    public function testMakeIndex()
    {
        VehicleValuation::factory(15)->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.valuations.index'));


        $response->assertStatus(200);
        $this->assertEquals(15, $response->json('total'));
        $this->assertArrayHasKey('name', $response->json('data.0'));
        $this->assertArrayHasKey('description', $response->json('data.0'));
        $this->assertArrayHasKey('metaItems', $response->json('data.0'));
        $this->assertArrayHasKey('link', $response->json('data.0'));
        $this->assertArrayHasKey('id', $response->json('data.0'));
    }

    public function testShow()
    {
        $model = VehicleValuation::factory()->create();

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->getJson(route('tenant.valuations.show', $model));

        $response->assertStatus(200);
        $this->assertEquals($model->provider, $response->json('provider'));
        $this->assertEquals($model->make, $response->json('make'));
        $this->assertEquals($model->retail_price, $response->json('retail_price'));
        $this->assertEquals($model->date_of_registration, $response->json('date_of_registration'));

    }

    public function testBadStore()
    {
        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.valuations.store'))->assertStatus(422);

        $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.valuations.store', [
                'registration_number' => 'FO21REL',
            ]))->assertStatus(422);

    }

    public function testStore()
    {
        Config::set('valuation.drivers.auto-trader.api_key', 'foo');
        Config::set('valuation.drivers.auto-trader.api_secret', 'baz');
        Config::set('valuation.drivers.auto-trader.merchant-id', '123');
        Config::set('valuation.drivers.auto-trader.live', false);
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'type' => 'string',
            'value' => true,
            'config_key' => 'valuation-auto-trader-enabled'
        ]);

        $prefix = 'https://api-sandbox.autotrader.co.uk';
        /** @var Vehicle $vehicle */
        $vehicle = Vehicle::factory()->create(['uuid' => 100]);
        Http::fake([
            $prefix . '/vehicles*' => $this->vehicleResponse(),
            $prefix . '/valuations*' => $this->valuationResponse(),
            $prefix . '/authenticate*' => Http::response(['access_token' => 'foo']),
            '*' => Http::response(null, 400),
        ]);


        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->withoutExceptionHandling()
            ->postJson(route('tenant.valuations.store', [
                'registration_number' => 'FO21REL',
                'mileage' => 5000
            ]));

        $response->assertStatus(201);
        $this->assertEquals(1000, $response->json('retail_price'));
        $this->assertEquals(4000, $response->json('clean_price'));
        $this->assertEquals(4000, $response->json('average_price'));
        $this->assertEquals(4000, $response->json('below_price'));
        $this->assertEquals('Hatchback', $response->json('body_type'));
        $this->assertEquals('FO21REL', $response->json('registration'));

        Http::assertSentCount(5);
        foreach (['Excellent', 'Good', 'Poor'] as $condition) {
            Http::assertSent(fn($request) =>
                str_starts_with($request->url(), $prefix . '/valuations')
                && ($request->data()['conditionRating'] ?? null) === $condition);
        }
    }

    public function testStoreBcaCondition()
    {
        Settings::make([
            'tab' => 'foo',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'dolor',
            'config_key' => 'valuation-bca-enabled',
            'type' => 'boolean',
            'value' => true,
        ]);

        Http::fake([
            'https://login.microsoftonline.com/ffbeab18-cefa-4aaf-9554-75a0af201128/oauth2/v2.0/token' => Http::response(
                [
                    'access_token' => 'abcdef',
                ],
                200
            ),
            'https://bca-apim-prod-gateway.api.bca.com/onlinevaluation/api/vehicles/abc123/specification' => Http::response([
                'vehicleSpecifications' => [
                    [
                        'identifier' => 'foo',
                        'colour' => 'blue',
                        'registrationDate' => '2020-01-01T00:00:00',
                        'vehicleType' => 'car',
                        'make' => 'bmw',
                    ],
                ],
                'correlationId' => '',
            ], 200),
            '*' => Http::response([
                'current' => [
                    'valuation' => 55000,
                ],
            ], 200),
        ]);

        $response = $this->actingAs($this->getUser())
            ->withHeader('X-Tenant', tenant('id'))
            ->postJson(route('tenant.valuations.store', [
                'registration_number' => 'abc123',
                'mileage' => 5000,
                'cosmetic_condition' => 'good',
            ]));

        $response->assertStatus(201);

        $this->assertCount(1, \Mtc\VehicleValuation\Models\VehicleValuation::where('cosmetic_condition', 'Good')->get());
    }

    private function vehicleResponse()
    {
        return Http::response([
            'vehicle' => [
                'derivativeId' => 'foo',
                'firstRegistrationDate' => '2005-01-01',
                'vehicleType' => 'car',
                'make' => 'BMW',
                'vin' => 'ABC123',
                'owners' => 'ABC123',
                'model' => '3 series GT',
                'derivative' => 'F34 318d',
                'fuelType' => 'Diesel',
                'engineSize' => 1999,
                'transmission' => 'Automatic',
                'bodyType' => 'Hatchback',
            ]
        ]);
    }

    private function valuationResponse()
    {
        return Http::response([
            'valuations' => [
                'retail' => [
                    'amountGBP' => 1000,
                ],
                'trade' => [
                    'amountGBP' => 2000,
                ],
                'private' => [
                    'amountGBP' => 3000,
                ],
                'partExchange' => [
                    'amountGBP' => 4000,
                ],
            ]

        ]);
    }

}
