<?php

namespace Tests\Unit;

use Tests\TestCase;

use App\Models\Tag;
use App\Models\Course;
use App\Models\CourseList;
use App\Models\StaffProfile;

class CourseListTest extends TestCase
{
    public function test_a_course_list_course_needs_a_tag_to_return_any_course()
    {
        $tag = Tag::factory()->create();
        $course_list = CourseList::factory()->create();
        $this->assertEquals(0, $course_list->courses->count());

        $course = Course::factory()->create();
        $course->addTag($tag);
        $course->publish();
        $course_list->addTag($tag);
        $course_list->refresh();
        cache()->tags([cache_name($course_list)])->flush();
        $this->assertEquals(1, $course_list->courses->count());
    }

    public function test_a_course_list_can_get_its_courses()
    {
        $tag = Tag::factory()->create();

        $course = Course::factory()->create();
        $course->publish();
        $course_list = CourseList::factory()->create();

        $course->addTag($tag);
        $course_list->addTag($tag);

        $this->assertNotNull($course_list->courses);
        $courses = $course_list->courses;

        $this->assertEquals(1, $courses->count());

        $this->assertEquals($course->id, $courses->first()->id);
    }

    public function test_a_course_must_include_all_tags_to_be_included()
    {
        $course1 = Course::factory()->create();
        $course2 = Course::factory()->create();

        $tag1 = Tag::factory()->create();
        $tag2 = Tag::factory()->create();

        $course1->addTag($tag1);
        $course1->addTag($tag2);

        $course2->addTag($tag1);

        $course1->publish();
        $course2->publish();

        $course_list = CourseList::factory()->create();
        $course_list->addTag($tag1);
        $course_list->addTag($tag2);

        $this->assertEquals(1, $course_list->courses->count());

        $this->assertTrue($course_list->courses->contains('id', $course1->id));
    }

    public function test_a_hidden_course_doesnt_show_up_in_a_course_list()
    {
        $course1 = Course::factory()->create();
        $course2 = Course::factory()->create();

        $tag = Tag::factory()->create();

        $course1->addTag($tag);
        $course2->addTag($tag);

        $version = $course2->versions()->first();
        $version->unlisted = true;
        $version->save();
        $course2->refresh();

        $course_list = CourseList::factory()->create();
        $course_list->addTag($tag);

        $course1->publish();
        $course2->publish();

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

        $this->assertEquals(1, $course_list->courses->count());

        $this->assertTrue($course_list->courses->contains('id', $course1->id));
        $this->assertFalse($course_list->courses->contains('id', $course2->id));
    }

    public function test_a_course_lists_courses_are_determined_by_and_tags_plus_exclude_tags()
    {
        $tag1 = Tag::factory()->create();
        $tag2 = Tag::factory()->create();
        $exclude_tag = Tag::factory()->create();

        $course1 = Course::factory()->create();
        $course2 = Course::factory()->create();
        $course_exclude = Course::factory()->create();

        $course1->addTag($tag1);
        $course1->addTag($tag2);
        $course2->addTag($tag1);
        $course2->addTag($tag2);

        $course_exclude->addTag($tag1);
        $course_exclude->addTag($tag2);
        $course_exclude->addTag($exclude_tag);

        $course_list = CourseList::factory()->create();
        $course_list->addTag($tag1);
        $course_list->addTag($tag2);
        $course_list->addExcludeTag($exclude_tag);

        $course1->publish();
        $course2->publish();
        $course_exclude->publish();

        $course_list->refresh();

        $courses = $course_list->courses;

        $this->assertEquals(2, $courses->count());
        $this->assertTrue($courses->contains('id', $course1->id));
        $this->assertTrue($courses->contains('id', $course2->id));
        $this->assertFalse($courses->contains('id', $course_exclude->id));
    }

    public function test_a_course_list_can_include_its_staff_profiles()
    {
        $tag = Tag::factory()->create();
        $staff_profile = StaffProfile::factory()->create();
        $course_list = CourseList::factory()->create([
            'show_profiles' => true,
        ]);

        $course_list->addTag($tag);
        $staff_profile->addTag($tag);

        $this->assertNotNull($course_list->staff_profiles);
        $this->assertEquals(1, $course_list->staff_profiles->count());
        $this->assertEquals($staff_profile->id, $course_list->staff_profiles->first()->id);
    }
}
