<?php

namespace Tests\Tenant;

use App\BookingRepository;
use App\Facades\Feature;
use Carbon\Carbon;
use Illuminate\Support\Facades\App;
use Mtc\MercuryDataModels\Booking;
use Mtc\VehicleLookup\VehicleLookupService;
use Tests\TenantTestCase;

class BookingTest extends TenantTestCase
{
    public function testAvailabilityThisYear()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability('jul', null, 1);

        $this->assertEquals('2020-06-29', $availability->first()[0]['full-date']);
    }

    public function testAvailabilityThisYearLastMonth()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability('dec', null, 1);

        $this->assertEquals('2020-12-31', $availability->last()[3]['full-date']);
        $this->assertEquals('2021-01-01', $availability->last()[4]['full-date']);
    }

    public function testAvailabilityWithNextYear()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability('jan', null, 1);

        $this->assertEquals('2020-12-31', $availability->first()[3]['full-date']);
        $this->assertEquals('2021-01-01', $availability->first()[4]['full-date']);
    }

    public function testAvailabilityWithExplicitYear()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability('jan', 2020, 1);

        $this->assertEquals('2019-12-30', $availability->first()[0]['full-date']);
        $this->assertEquals('2020-01-01', $availability->first()[2]['full-date']);
    }

    public function testAvailabilityWithExplicitFutureYear()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability('jan', 2022, 1);

        $this->assertEquals('2021-12-27', $availability->first()[0]['full-date']);
        $this->assertEquals('2022-01-01', $availability->first()[5]['full-date']);
    }

    public function testAvailabilityWithExplicitPastYear()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability('jan', 2019, 1);

        $this->assertEquals('2018-12-31', $availability->first()[0]['full-date']);
        $this->assertEquals('2019-01-01', $availability->first()[1]['full-date']);
    }

    public function testAvailabilityWithExplicitYearNoMonth()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability(null, 2021, 1);

        $this->assertEquals('2021-05-31', $availability->first()[0]['full-date']);
        $this->assertEquals('2021-06-01', $availability->first()[1]['full-date']);
    }

    public function testAvailabilityWithExplicitCurrentMonthAndYear()
    {
        Carbon::setTestNow('2020-06-01');
        $availability = (App::make(BookingRepository::class))->getAvailability('jun', 2020, 1);

        $this->assertEquals('2020-06-01', $availability->first()[0]['full-date']);
    }

    public function testVehicleLookupFallsBackToDraftWithoutDetailsWhenLookupFails()
    {
        Feature::setEnabled(tenant(), ['service-booking']);

        $lookup = \Mockery::mock(VehicleLookupService::class);
        $lookup->shouldReceive('findByVRM')
            ->once()
            ->andThrow(new \RuntimeException('AutoTrader was not able to find vehicle'));
        $this->app->instance(VehicleLookupService::class, $lookup);

        $response = $this->postJson('frontend/service-booking/vehicle-lookup', [
            'registration_number' => 'XX00XXX',
            'mileage' => 10000,
        ]);

        // A failed lookup no longer blocks the journey: the customer can still book,
        // just without verified vehicle details.
        $response->assertStatus(201);
        $response->assertJsonPath('booking.registration_number', 'XX00XXX');
        $response->assertJsonPath('booking.vehicle_data.make', null);
        $response->assertJsonPath('booking.vehicle_data.model', null);
        $response->assertJsonPath('notice', 'We could not verify your vehicle details, but you can still continue with your booking.');

        // The draft must still be created so the rest of the flow has a booking to work with.
        $this->assertCount(1, Booking::all());
    }
}
