<?php

namespace Tests\Feature;

use App\Console\Commands\PopulateDealershipDepartments;
use App\Facades\Settings;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Mtc\MercuryDataModels\Dealership;
use Mtc\MercuryDataModels\DealershipDepartment;
use Tests\TestCase;

class DealershipDepartmentPopulationTest extends TestCase
{
    use RefreshDatabase;

    protected $tenancy = true;

    public function testPopulationCommand()
    {
        $dealership_1 = Dealership::factory()->create([
            'name' => 'foo',
            'open_times' => [
                'test'
            ],
        ]);

        $dealership_2 = Dealership::factory()->create([
            'name' => 'baz',
            'open_times' => [
                'test'
            ],
            'alt_open_times' => [
                'test_alt'
            ],
        ]);

        $dealership_3 = Dealership::factory()->create([
            'name' => 'bar',
            'open_times' => [
                'test'
            ],
            'alt_open_times' => [
                'test_alt'
            ],
            'second_alt_open_times' => [
                'test_alt'
            ],
        ]);

        DealershipDepartment::query()->create([
            'dealership_id' => $dealership_1->id,
            'open_times' => [],
        ]);

        // assert that we have expected number of departments
        $this->assertCount(1, DealershipDepartment::all());
        $this->assertCount(1, DealershipDepartment::query()->where('dealership_id', '=', $dealership_1->id)->get());

        // run the command
        $this->artisan(PopulateDealershipDepartments::class);

        // assert that we didn't add departments for dealership with existing departments
        $this->assertCount(1, DealershipDepartment::query()->where('dealership_id', '=', $dealership_1->id)->get());

        // assert that expected departments were added
        $this->assertCount(6, DealershipDepartment::all());
        $this->assertCount(2, DealershipDepartment::query()->where('dealership_id', '=', $dealership_2->id)->get());
        $this->assertCount(3, DealershipDepartment::query()->where('dealership_id', '=', $dealership_3->id)->get());

        // assert that we only have one is_primary for each dealer's departments
        $this->assertCount(3, DealershipDepartment::query()->where('is_primary', '=', true)->get());
        $this->assertCount(
            1,
            DealershipDepartment::query()
                ->where('is_primary', '=', true)
                ->where('dealership_id', '=', $dealership_1->id)
            ->get()
        );
        $this->assertCount(
            1,
            DealershipDepartment::query()
                ->where('is_primary', '=', true)
                ->where('dealership_id', '=', $dealership_2->id)
                ->get()
        );
        $this->assertCount(
            1,
            DealershipDepartment::query()
                ->where('is_primary', '=', true)
                ->where('dealership_id', '=', $dealership_3->id)
                ->get()
        );
    }

    public function testRepeatRuns()
    {
        $dealership_1 = Dealership::factory()->create([
            'name' => 'foo',
            'open_times' => [
                'test'
            ],
        ]);

        $dealership_2 = Dealership::factory()->create([
            'name' => 'baz',
            'open_times' => [
                'test'
            ],
            'alt_open_times' => [
                'test_alt'
            ],
        ]);

        $dealership_3 = Dealership::factory()->create([
            'name' => 'bar',
            'open_times' => [
                'test'
            ],
            'alt_open_times' => [
                'test_alt'
            ],
            'second_alt_open_times' => [
                'test_alt'
            ],
        ]);

        $this->assertCount(0, DealershipDepartment::all());

        // run the command
        $this->artisan(PopulateDealershipDepartments::class);

        // assert that expected departments were added
        $this->assertCount(6, DealershipDepartment::all());

        // run the command again
        $this->artisan(PopulateDealershipDepartments::class);

        // assert that expected departments were added
        $this->assertCount(6, DealershipDepartment::all());
        $this->assertCount(1, DealershipDepartment::query()->where('dealership_id', '=', $dealership_1->id)->get());
        $this->assertCount(2, DealershipDepartment::query()->where('dealership_id', '=', $dealership_2->id)->get());
        $this->assertCount(3, DealershipDepartment::query()->where('dealership_id', '=', $dealership_3->id)->get());
    }

    public function testContactDetails()
    {
        $dealership_1 = Dealership::factory()->create([
            'name' => 'foo',
            'open_times' => [
                'test'
            ],
            'email' => 'dealer_1 email',
            'contact_no' => 'dealer_1 phone',
        ]);

        $dealership_2 = Dealership::factory()->create([
            'name' => 'baz',
            'open_times' => [
                'test'
            ],
            'alt_open_times' => [
                'test_alt'
            ],
            'email' => 'dealer_2 email',
            'contact_no' => 'dealer_2 phone',
        ]);

        $dealership_3 = Dealership::factory()->create([
            'name' => 'bar',
            'open_times' => [
                'test'
            ],
            'alt_open_times' => [
                'test_alt'
            ],
            'second_alt_open_times' => [
                'test_alt'
            ],
            'email' => 'dealer_3 email',
            'contact_no' => 'dealer_3 phone',
        ]);

        // run the command
        $this->artisan(PopulateDealershipDepartments::class);

        $this->assertCount(6, DealershipDepartment::all());

        $this->assertCount(
            1,
            DealershipDepartment::query()
                ->where('dealership_id', '=', $dealership_1->id)
                ->where('email', '=', $dealership_1->email)
                ->where('contact_no', '=', $dealership_1->contact_no)
            ->get()
        );

        $this->assertCount(
            2,
            DealershipDepartment::query()
                ->where('dealership_id', '=', $dealership_2->id)
                ->where('email', '=', $dealership_2->email)
                ->where('contact_no', '=', $dealership_2->contact_no)
                ->get()
        );

        $this->assertCount(
            3,
            DealershipDepartment::query()
                ->where('dealership_id', '=', $dealership_3->id)
                ->where('email', '=', $dealership_3->email)
                ->where('contact_no', '=', $dealership_3->contact_no)
                ->get()
        );
    }

    public function testDepartmentNaming()
    {
        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'debug',
            'config_key' => 'dealership-secondary-open-close-time-name',
            'value' => null,
            'type' => 'string',
        ]);

        Settings::make([
            'tab' => 'foo-baz',
            'section' => 'lorem',
            'group' => 'ipsum',
            'name' => 'debug',
            'config_key' => 'dealership-tertiary-open-close-time-name',
            'value' => 'foo',
            'type' => 'string',
        ]);

        Dealership::factory()->create([
            'name' => 'bar',
            'open_times' => [
                'test'
            ],
            'alt_open_times' => [
                'test_alt'
            ],
            'second_alt_open_times' => [
                'second_test_alt'
            ],
        ]);

        // run the command
        $this->artisan(PopulateDealershipDepartments::class);

        $this->assertCount(3, DealershipDepartment::all());

        $this->assertCount(
            1,
            DealershipDepartment::query()
                ->where('name', '=', 'General')
                ->get()
        );

        $this->assertCount(
            1,
            DealershipDepartment::query()
                ->where('name', '=', 'Department Two')
                ->get()
        );

        $this->assertCount(
            1,
            DealershipDepartment::query()
                ->where('name', '=', 'foo')
                ->get()
        );
    }
}
