<?php

namespace Tests\Feature;

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

use Illuminate\Support\Str;
use Illuminate\Support\Arr;

use App\Models\CourseDescription;
use App\Models\Course;
use App\Models\Tag;
use App\Models\ContentElement;
use App\Models\TextBlock;

use Tests\Feature\ContentElementsTestTrait;
use Tests\Feature\ContentElementsSearchTestTrait;

class CourseDescriptionTest extends TestCase
{
    use WithFaker;
    use ContentElementsTestTrait;
    use ContentElementsSearchTestTrait;

    protected function getClassname()
    {
        return 'course-description';
    }

    public function test_a_course_description_can_be_created()
    {
        $course = Course::factory()->create();
        $course_description_input = CourseDescription::factory()->raw();

        $input = [
            'pivot' => $this->getContentableArray($course),
            'type' => Str::kebab(class_basename(CourseDescription::class)),
            'content' => $course_description_input,
        ];

        $this->signInAdmin();
        $this->enableEditing();

        $this->json('POST', route('content-elements.store'), $input)
             ->assertSuccessful()
             ->assertJsonFragment([
                 'success' => 'Course Description Saved',
             ]);

        $content_element = ContentElement::all()->last();
        $this->assertInstanceOf(ContentElement::class, $content_element);

        $course_description = $content_element->content;

        $this->assertNotNull($course_description->header);
        $this->assertNotNull($course_description->body);
        $this->assertNotNull($course_description->credit);

        $this->assertEquals(Arr::get($input, 'content.header'), $course_description->header);
        $this->assertEquals(Arr::get($input, 'content.body'), $course_description->body);
        $this->assertEquals(Arr::get($input, 'content.credit'), $course_description->credit);

        $course->refresh();
        $this->assertEquals(1, $course->contentElements()->count());
        $this->assertEquals(Arr::get($input, 'content.header'), $course->contentElements()->first()->content->header);
    }

    public function test_a_course_description_can_be_updated()
    {
        $course = Course::factory()->create();
        $content_element = $this->createContentElement(CourseDescription::factory(), $course);
        $course_description = $content_element->content;

        $old_header = $course_description->header;
        $old_body = $course_description->body;
        $old_credit = $course_description->credit;

        $input = $content_element->toArray();
        $input['content'] = array_merge($course_description->toArray(), CourseDescription::factory()->raw());
        $input['pivot'] = $this->getContentableArray($course);

        $this->signInAdmin();
        $this->enableEditing();

        $this->json('POST', route('content-elements.update', ['id' => $content_element->id]), $input)
             ->assertSuccessful()
             ->assertJsonFragment([
                 'success' => 'Course Description Saved',
             ]);

        $course_description->refresh();

        $this->assertEquals($content_element->id, ContentElement::all()->last()->id);
        $this->assertEquals($course_description->id, CourseDescription::all()->last()->id);

        $this->assertNotEquals($old_header, $course_description->header);
        $this->assertNotEquals($old_body, $course_description->body);
        $this->assertNotEquals($old_credit, $course_description->credit);
        $this->assertEquals(Arr::get($input, 'content.header'), $course_description->header);
        $this->assertEquals(Arr::get($input, 'content.body'), $course_description->body);
        $this->assertEquals(Arr::get($input, 'content.credit'), $course_description->credit);
    }

    public function test_a_course_description_can_be_searched_for()
    {
        $course = Course::factory()->create();
        $terms = Str::random(8);
        $content_element = $this->createContentElement(TextBlock::factory(['body' => $terms]), $course);
        $content_element2 = $this->createContentElement(TextBlock::factory(['body' => Str::random(12)]), $course);
        $course->publish();

        $this->get($course->full_slug)
            ->assertSuccessful();

        $this->withoutExceptionHandling();
        $this->json('POST', route('search'), ['terms' => $terms])
             ->assertSuccessful()
             ->assertJsonFragment([
                'title' => $content_element->content->header,
             ])
             ->assertJsonMissing([
                'title' => $content_element2->content->header,
             ]);
    }
}
