<?php

namespace Tests\Unit;

use Tests\TestCase;

use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Str;
use App\Utilities\SearchResult;
use App\Utilities\PageLink;
use App\Models\Page;
use App\Models\Blog;
use App\Models\TextBlock;
use App\Models\PhotoBlock;
use App\Models\ContentElement;

class SearchResultTest extends TestCase
{
    use WithFaker;

    public function test_a_search_result_can_be_created()
    {
        $page = Page::factory()->create();

        $header = $this->faker->sentence;
        $term = Str::random(12);

        $content_element = $this->createContentElement(TextBlock::factory([
            'header' => $header,
            'body' => '<p>'.$this->faker->paragraph.' '.$term.'</p>',
        ]), $page);
        $text_block = $content_element->content;
        $page->publish();

        $this->assertNotNull($text_block->getSearchResultTitle('foobar'));
        $this->assertNotNull($text_block->getSearchResultPreview([$term]));
        $this->assertNotNull($text_block->getSearchResultRank([$term]));

        $search_results = SearchResult::search($term);

        $this->assertEquals(1, $search_results->count());
        $search_result = $search_results->first();

        $this->assertNotNull($search_result->type);
        $this->assertNotNull($search_result->id);
        $this->assertNotNull($search_result->url);
        $this->assertNotNull($search_result->title);
        $this->assertNotNull($search_result->preview);
        $this->assertNotNull($search_result->rank);
        $this->assertNotNull($search_result->url_text);

        $this->assertEquals($page->type, $search_result->type);
        $this->assertEquals($page->id, $search_result->id);
        $this->assertEquals('/'.$page->full_slug.'#'.PageLink::convertAnchorText($header), $search_result->url);
        $this->assertEquals($text_block->getSearchResultTitle('foobar'), $search_result->title);
        $this->assertEquals($text_block->getSearchResultPreview([$term]), $search_result->preview);
        //$this->assertEquals($text_block->getSearchResultRank([$term]), $search_result->rank);
        $this->assertEquals(Str::title($page->full_slug.' > '.$content_element->content->header), $search_result->url_text);
        $this->assertEquals($page->published_at, $search_result->date);
    }

    /*
    public function an_unpublished_search_result_has_a_date()
    {
        $this->signInAdmin();
        $this->enableEditing();

        $page = Page::factory()->create();

        $header = $this->faker->sentence;
        $term = Str::random(12);

        $content_element = $this->createContentElement(TextBlock::factory([
            'header' => $header,
            'body' => '<p>'.$this->faker->paragraph.' '.$term.'</p>',
        ]), $page);
        $text_block = $content_element->content;

        $this->assertTrue(auth()->user()->can('update', $content_element));

        $search_results = SearchResult::search($term);
        $this->assertEquals(1, $search_results->count());
        $search_result = $search_results->first();

        $this->assertEquals($content_element->updated_at, $search_result->date);
    }
     */

    public function test_a_body_string_is_truncated_for_a_search_result_preview()
    {
        $page = Page::factory()->create();

        $paragraph1 = $this->faker->paragraph;
        $term = Str::random(12);
        $paragraph2 = $this->faker->paragraph;
        $body = '<p>'.$paragraph1.'</p><p>'.$term.'</p><p>'.$paragraph2.'</p>';

        $text_block = $this->createContentElement(TextBlock::factory([
            'body' => $body,
        ]), $page)->content;

        $this->assertEquals($body, $text_block->body);
        $preview = $text_block->getSearchResultPreview([$term]);
        $this->assertNotNull($preview);
        $this->assertTrue(Str::contains($preview, $term));
        $this->assertNotEquals($body, $preview);
    }

    public function test_the_preview_is_created_correctly_for_a_search_result()
    {
        $page = Page::factory()->create();

        $body = '<p>At Brentwood our unique boarding life program and progressive scheduling provides students with unrivaled opportunities to discover who they want to be. Our staff get to know who the students really are and by doing so can provide the support they need in all areas of their education. Students live in a contemporary setting, surrounded by caring friends and mentors. They can be themselves and develop relationships that last well beyond their years at Brentwood.</p>';

        $text_block = $this->createContentElement(TextBlock::factory([
            'body' => $body,
        ]), $page)->content;

        $preview = $text_block->getSearchResultPreview(['Brentwood']);
        $needle = 'At Brentwood our unique boarding life program and progressive scheduling provides students with unrivaled opportunities ...  develop relationships that last well beyond their years at Brentwood.';
        $this->assertEquals($needle, $preview);

        $preview = $text_block->getSearchResultPreview(['brentwood']);
        $this->assertEquals($needle, $preview);
    }

    public function test_two_close_words_can_be_returned_in_the_same_search_result_preview()
    {
        $page = Page::factory()->create();

        $body = '<p>At Brentwood our unique boarding life program and progressive scheduling provides students with unrivaled opportunities to discover who they want to be. Our staff get to know who the students really are and by doing so can provide the support they need in all areas of their education. Students live in a contemporary setting, surrounded by caring friends and mentors. They can be themselves and develop relationships that last well beyond their years at Brentwood.</p>';

        $text_block = $this->createContentElement(TextBlock::factory([
            'body' => $body,
        ]), $page)->content;

        $preview = $text_block->getSearchResultPreview(['brentwood', 'boarding']);
        $needle = 'At Brentwood our unique boarding life program and progressive scheduling provides students with unrivaled opportunities ...  develop relationships that last well beyond their years at Brentwood.';
        $this->assertEquals($needle, $preview);
    }

    public function test_two_apart_words_can_be_returned_in_the_same_search_result_preview()
    {
        $page = Page::factory()->create();

        $body = '<p>At Brentwood our unique boarding life program and progressive scheduling provides students with unrivaled opportunities to discover who they want to be. Our staff get to know who the students really are and by doing so can provide the support they need in all areas of their education. Students live in a contemporary setting, surrounded by caring friends and mentors. They can be themselves and develop relationships that last well beyond their years at Brentwood.</p><p>Our unique tripartite schedule offers the flexibility for students to be involved in a wide variety of academics, athletics, arts and extra curricular activities. Academics are held in the morning followed by alternating afternoons of arts and athletics. Our student led clubs and activities are integrated throughout the remainder of the week including featured events on the weekends. As a result there is no shortage of things to keep students busy. We find the students who get the most out of this tripartite schedule are the ones who want to explore and discover who they are by trying a wide variety of courses and activities.</p>';

        $text_block = $this->createContentElement(TextBlock::factory([
            'body' => $body,
        ]), $page)->content;

        $preview = $text_block->getSearchResultPreview(['brentwood', 'activities']);
        $needle = 'At Brentwood our unique boarding life program and progressive scheduling provides students with unrivaled opportunities ...  develop relationships that last well beyond their years at Brentwood.  Our unique tripartite schedule offers the flexibility ...  variety of academics, athletics, arts and extra ... ';
        $this->assertEquals($needle, $preview);
    }

    /*
    public function the_preview_starts_and_ends_with_a_p_tag()
    {
        $page = Page::factory()->create();

        $body = '<p>At Brentwood our unique boarding life program and progressive scheduling provides students with unrivaled opportunities to discover who they want to be. Our staff get to know who the students really are and by doing so can provide the support they need in all areas of their education. Students live in a contemporary setting, surrounded by caring friends and mentors. They can be themselves and develop relationships that last well beyond their years at Brentwood.</p>';

        $text_block = $this->createContentElement(TextBlock::factory([
            'body' => $body,
        ]), $page)->content;

        $preview = $text_block->getSearchResultPreview(['education']);
        $this->assertTrue(Str::startsWith($preview, '<p>'));
        $this->assertTrue(Str::endsWith($preview, '</p>'));
    }
     */

    public function test_only_slashes_with_characters_after_them_are_replace_with_greater_thans()
    {
        $string1 = '//';
        $string2 = 'why-brentwood';
        $string3 = 'why-brentwood/oceanfront-campus';
        $string4 = 'why-brentwood/oceanfront-campus/';
        $string5 = 'why-brentwood/oceanfront-campus/life';

        $this->assertEquals('', SearchResult::urlText($string1));
        $this->assertEquals('Why Brentwood', SearchResult::urlText($string2));
        $this->assertEquals('Why Brentwood > Oceanfront Campus', SearchResult::urlText($string3));
        $this->assertEquals('Why Brentwood > Oceanfront Campus', SearchResult::urlText($string4));
        $this->assertEquals('Why Brentwood > Oceanfront Campus > Life', SearchResult::urlText($string5));
    }

    public function test_seaching_content_elements_with_filters_returns_only_pageables_in_the_filter()
    {
        $header = $this->faker->sentence;
        $term = Str::random(12);

        $page = Page::factory()->create();
        $blog = Blog::factory()->create();

        $content_element1 = $this->createContentElement(TextBlock::factory([
            'header' => $header,
            'body' => '<p>'.$this->faker->paragraph.' '.$term.'</p>',
        ]), $page);

        $content_element2 = $this->createContentElement(TextBlock::factory([
            'header' => $header,
            'body' => '<p>'.$this->faker->paragraph.' '.$term.'</p>',
        ]), $blog);

        $page->publish();
        $blog->publish();


        $filters = collect([
            'pages',
            'livestreams',
        ]);

        $results = ContentElement::searchResults(collect([$term]), $filters);

        $this->assertEquals(1, $results->count());
    }
}
