<?php

namespace Tests\Feature;

use App\Models\AdminUser;
use App\Models\Expertise;
use App\Models\WorkAreaExpertise;
use App\Models\WorkAreas; 
use App\Modules\Admin\Libraries\WorkAreaModule;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;

use Laravel\Sanctum\Sanctum;

use Tests\TestCase;

class SystemLibraryWorkAreaTest extends TestCase
{
    use RefreshDatabase; 

    private WorkAreas $workArea; 

    /**
     * Set Up Test
     * 
     * @return void 
     */
    protected function setUp(): void
    {
        //! php artisan test --filter SystemLibraryWorkAreaTest 
        parent::setUp();

        $superAdmin = AdminUser::factory()->create();

        Sanctum::actingAs(
            $superAdmin,
            ['*']
        );

        $this->workArea = WorkAreas::factory()
            ->state(
                [
                    'name' => "Data Analytics"
                ]
            )
            ->create();
    }
    /**
     * Test List Items
     * 
     * @return void 
     */
    public function test_list(): void
    {
        WorkAreas::factory()->count(20)->create();

        $response = (new WorkAreaModule())->getData([]);

        $this->assertTrue($response->status() == 200, "HTTP Status Code is 200");

        $data = $response->getData(true);

        $this->assertIsArray($data);
        $this->assertArrayHasKey('data', $data);
        $this->assertArrayHasKey('links', $data);
        $this->assertArrayHasKey('meta', $data);

        $this->assertTrue(count($data['data']) >= 10);
    }

    /**
     * Test View Item 
     * 
     * @return void 
     */
    public function test_view(): void
    {
        $response = (new WorkAreaModule())->getDetails($this->workArea->id);

        $this->assertTrue($response->status() == 200, "HTTP Status Code is 200");

        $data = $response->getData(true);

        $this->assertTrue(count($data['data']) >= 1);

        $this->assertEquals('Data Analytics', $data['data'][0]['name'], "Retrieved Item's name must be 'Data Analytics'");
    }

    /**
     * Test Create Item
     * 
     * @return void 
     */
    public function test_create(): void
    {
        $expertisesId = [];

        $expertises = Expertise::factory()
            ->count(5)
            ->create();

        foreach ($expertises as $expertise) 
        {
            array_push($expertisesId, $expertise['id']);
        }

        $response = (new WorkAreaModule())->storeData(
            [
                "name"       => "Embedded Programming",
                "expertises" => $expertisesId,
            ]
        );

        $this->assertDatabaseHas(
            WorkAreas::class,
            [
                'name' => 'Embedded Programming'
            ]
        );

        $lastInsertedWorkArea = WorkAreas::query()
            ->where('name', '=', 'Embedded Programming')
            ->firstOrFail();

        $this->assertTrue($response->status() == 201, "HTTP Status Code is 201");

        $this->assertDatabaseHas(
            WorkAreas::class,
            [
                'id'   => $lastInsertedWorkArea->id,
                'name' => 'Embedded Programming'
            ]
        );

        foreach($expertises as $expertise) 
        {
            $this->assertDatabaseHas(
                WorkAreaExpertise::class,
                [
                    "expertise_id" => $expertise['id'],
                    "work_area_id" => $lastInsertedWorkArea->id
                ]
            );
        }
    }

    /**
     * Test Update Item
     * 
     * @return void 
     */
    public function test_update(): void
    {
        $expertisesId = [];

        $expertises = Expertise::factory()
            ->count(5)
            ->create();

        foreach ($expertises as $expertise) 
        {
            array_push($expertisesId, $expertise['id']);
        }

        $response = (new WorkAreaModule())->updateData(
            [
                "name"        => "Artificial Intelligence",
                "expertises"  => $expertisesId, 
            ], 
            $this->workArea->id  
        );

        $this->assertTrue($response->status() == 200, "HTTP Status Code is 200");

        $this->assertDatabaseHas(
            WorkAreas::class,
            [
                "id"   => $this->workArea->id,
                "name" => "Artificial Intelligence"
            ]
        );

        foreach ($expertises as $expertise) 
        {
            $this->assertDatabaseHas(
                WorkAreaExpertise::class,
                [
                    "expertise_id" => $expertise['id'],
                    "work_area_id" => $this->workArea->id
                ]
            );
        }
    }

    /**
     * Test Delete Item
     * 
     * @return void 
     */
    public function test_delete(): void
    {
        $currentTableCount = WorkAreas::count();

        $response = (new WorkAreaModule())->deleteData(
            $this->workArea->id
        );

        $this->assertTrue($response->status() == 200, "HTTP Status Code is 200");

        $this->assertDatabaseCount('work_areas', ($currentTableCount - 1));
    }
}
