<?php

namespace Tests\Tenant;

use App\PageRepository;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Collection;
use Mtc\ContentManager\PageStatus;
use Mtc\MercuryDataModels\Page;
use Mtc\MercuryDataModels\ResourceView;
use Tests\TenantTestCase;

class PageRepositoryTest extends TenantTestCase
{
    public function testListing()
    {
        $newest_foo = Page::factory(1)->create([
            'category' => 'foo',
            'published_at' => Carbon::now()->subDays(),
            'status' => PageStatus::PUBLISHED->value,
        ]);
        Page::factory(5)->create([
            'category' => 'foo',
            'published_at' => Carbon::now()->subDays(2),
            'status' => PageStatus::PUBLISHED->value,
        ]);
        $oldest_foo = Page::factory(1)->create(['category' => 'foo', 'published_at' => Carbon::now()->subDays(3)]);

        Page::factory(1)->create(['category' => 'baz', 'published_at' => Carbon::now()->subDays(4)]);
        Page::factory(10)->create(['category' => 'baz', 'published_at' => Carbon::now()->subDays(5)]);
        $oldest_baz = Page::factory(1)->create(['category' => 'baz', 'published_at' => Carbon::now()->subDays(5)]);

        $repository = (new PageRepository());
        $listing = $repository->listing('foo');
        $this->assertInstanceOf(Collection::class, $listing);
        $this->assertEquals(6, $listing->count());
        $this->assertTrue($newest_foo->first()->is($listing->first()));


        $listing = $repository->listing('foo', 10);
        $this->assertEquals(6, $listing->count());
    }

    public function testListingOrderByPopular()
    {
        $page1 = Page::factory()->create([
            'category' => 'blog',
            'published_at' => Carbon::now()->subDays(5),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        $page2 = Page::factory()->create([
            'category' => 'blog',
            'published_at' => Carbon::now()->subDays(4),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        $page3 = Page::factory()->create([
            'category' => 'blog',
            'published_at' => Carbon::now()->subDays(3),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        // Create view records - page2 should have most views
        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page1->id,
            'date' => Carbon::now()->format('Y-m-d'),
            'hits' => 5,
        ]);

        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page2->id,
            'date' => Carbon::now()->format('Y-m-d'),
            'hits' => 100,
        ]);

        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page3->id,
            'date' => Carbon::now()->format('Y-m-d'),
            'hits' => 50,
        ]);

        $repository = new PageRepository();
        $listing = $repository->listing('blog', 10, 'popular');

        $this->assertInstanceOf(Collection::class, $listing);
        $this->assertEquals(3, $listing->count());

        // Most popular (page2) should be first
        $this->assertEquals($page2->id, $listing->first()->id);
        $this->assertEquals($page3->id, $listing->get(1)->id);
        $this->assertEquals($page1->id, $listing->last()->id);
    }

    public function testListingOrderByTrending()
    {
        $page1 = Page::factory()->create([
            'category' => 'news',
            'published_at' => Carbon::now()->subDays(5),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        $page2 = Page::factory()->create([
            'category' => 'news',
            'published_at' => Carbon::now()->subDays(4),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        $page3 = Page::factory()->create([
            'category' => 'news',
            'published_at' => Carbon::now()->subDays(3),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        // Create old view records (outside 30 day window) - should not count for trending
        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page1->id,
            'date' => Carbon::now()->subDays(60)->format('Y-m-d'),
            'hits' => 1000,
        ]);

        // Create recent view records (within 30 day window)
        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page1->id,
            'date' => Carbon::now()->format('Y-m-d'),
            'hits' => 5,
        ]);

        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page2->id,
            'date' => Carbon::now()->subDays(10)->format('Y-m-d'),
            'hits' => 80,
        ]);

        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page3->id,
            'date' => Carbon::now()->subDays(5)->format('Y-m-d'),
            'hits' => 30,
        ]);

        $repository = new PageRepository();
        $listing = $repository->listing('news', 10, 'trending');

        $this->assertInstanceOf(Collection::class, $listing);
        $this->assertEquals(3, $listing->count());

        // Trending (page2 with 80 recent hits) should be first
        $this->assertEquals($page2->id, $listing->first()->id);
        $this->assertEquals($page3->id, $listing->get(1)->id);
        $this->assertEquals($page1->id, $listing->last()->id);
    }

    public function testListingWithNoViewsOrdersCorrectly()
    {
        $page1 = Page::factory()->create([
            'category' => 'articles',
            'published_at' => Carbon::now()->subDays(5),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        $page2 = Page::factory()->create([
            'category' => 'articles',
            'published_at' => Carbon::now()->subDays(4),
            'status' => PageStatus::PUBLISHED->value,
        ]);

        // Only page1 has views
        ResourceView::query()->create([
            'viewable_type' => 'page',
            'viewable_id' => $page1->id,
            'date' => Carbon::now()->format('Y-m-d'),
            'hits' => 10,
        ]);

        $repository = new PageRepository();
        $listing = $repository->listing('articles', 10, 'popular');

        $this->assertEquals(2, $listing->count());
        // page1 with views should be first
        $this->assertEquals($page1->id, $listing->first()->id);
        // page2 with no views should be second
        $this->assertEquals($page2->id, $listing->last()->id);
    }
}
