<?php

namespace Tests\Tenant;

use App\DealershipRepository;
use Illuminate\Support\Facades\App;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\DealershipDepartment;
use Mtc\MercuryDataModels\DealershipHoliday;
use Mtc\MercuryDataModels\Franchise;
use Tests\TenantTestCase;

class DealershipRepositoryTest extends TenantTestCase
{
    public function testExportToRemote()
    {
        $franchise = Franchise::query()->create([
            'name' => 'Acme',
            'slug' => 'acme',
        ]);
        $dealership = Dealership::factory()->create([
            'name' => 'Acme Manchester',
            'franchise_id' => $franchise->id,
        ]);
        DealershipDepartment::query()->create([
            'name' => 'Sales',
            'dealership_id' => $dealership->id,
            'is_primary' => true,
        ]);
        DealershipDepartment::query()->create([
            'name' => 'Service',
            'dealership_id' => $dealership->id,
            'is_primary' => false,
        ]);
        DealershipHoliday::query()->create([
            'dealership_id' => $dealership->id,
            'date' => now()->addWeek()->toDateString(),
            'note' => 'Bank Holiday',
        ]);

        $export = $this->repository()->exportToRemote([$dealership->id]);

        $this->assertCount(1, $export);
        $this->assertEquals($dealership->name, $export[0]['name']);
        $this->assertEquals($dealership->slug, $export[0]['slug']);
        $this->assertEquals('acme', $export[0]['franchise']);
        $this->assertArrayNotHasKey('franchise_id', $export[0]);
        $this->assertCount(2, $export[0]['departments']);
        $this->assertEqualsCanonicalizing(
            ['Sales', 'Service'],
            collect($export[0]['departments'])->pluck('name')->toArray()
        );
        $this->assertCount(1, $export[0]['holidays']);
        $this->assertEquals('Bank Holiday', $export[0]['holidays'][0]['note']);
    }

    public function testCanBeImported()
    {
        $repository = $this->repository();

        $this->assertTrue($repository->canBeImported(['slug' => 'foo']));

        Dealership::factory()->create(['name' => 'Foo Branch']);
        $existing = Dealership::query()->first();

        $this->assertFalse($repository->canBeImported(['slug' => $existing->slug]));
    }

    public function testCheckImportEntryValidity()
    {
        $repository = $this->repository();

        $check = $repository->checkImportEntryValidity(['slug' => 'fresh-branch'], []);
        $this->assertEmpty($check['errors']);

        $missing = $repository->checkImportEntryValidity(['slug' => ''], []);
        $this->assertNotEmpty($missing['errors']);

        Dealership::factory()->create(['name' => 'Existing Branch']);
        $existing = Dealership::query()->first();

        $taken = $repository->checkImportEntryValidity(['slug' => $existing->slug], []);
        $this->assertNotEmpty($taken['errors']);
    }

    public function testImportRecord()
    {
        $franchise = Franchise::query()->create([
            'name' => 'Acme',
            'slug' => 'acme',
        ]);

        $entry = [
            'name' => 'Acme Liverpool',
            'slug' => 'acme-liverpool',
            'email' => 'liverpool@example.test',
            'active' => true,
            'city' => 'Liverpool',
            'franchise' => 'acme',
            'departments' => [
                [
                    'name' => 'Sales',
                    'is_primary' => true,
                    'open_times' => [],
                ],
                [
                    'name' => 'Aftersales',
                    'is_primary' => false,
                    'open_times' => [],
                ],
            ],
            'holidays' => [
                ['date' => now()->addWeek()->toDateString(), 'note' => 'Closed for staff training'],
            ],
            'franchises' => ['acme'],
        ];

        $this->assertTrue($this->repository()->importRecord($entry));

        $dealership = Dealership::query()->where('slug', 'acme-liverpool')->first();
        $this->assertNotNull($dealership);
        $this->assertEquals($franchise->id, $dealership->franchise_id);
        $this->assertCount(2, $dealership->departments);
        $this->assertCount(1, $dealership->allHolidays);
        $this->assertCount(1, $dealership->franchises);
    }

    private function repository(): DealershipRepository
    {
        return App::make(DealershipRepository::class);
    }
}
