<?php

namespace Tests\Unit\Models;

use App\Enums\ActivityTypeEnum;
use App\Models\ActivityLog;
use App\Models\Article;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ActivityLogTest extends TestCase
{
    use RefreshDatabase;

    public function test_of_type_returns_only_that_type(): void
    {
        ActivityLog::factory()->type(ActivityTypeEnum::PUBLISH)->create();
        ActivityLog::factory()->type(ActivityTypeEnum::FETCH)->create();

        $results = ActivityLog::ofType(ActivityTypeEnum::PUBLISH)->get();

        $this->assertCount(1, $results);
        $this->assertSame(ActivityTypeEnum::PUBLISH, $results->first()->type);
    }

    public function test_since_excludes_entries_before_the_window(): void
    {
        ActivityLog::factory()->loggedAt(now()->subHours(2))->create(['message' => 'inside']);
        ActivityLog::factory()->loggedAt(now()->subDays(3))->create(['message' => 'outside']);

        $results = ActivityLog::since(now()->subDay())->get();

        $this->assertCount(1, $results);
        $this->assertSame('inside', $results->first()->message);
    }

    public function test_latest_first_orders_newest_before_oldest(): void
    {
        ActivityLog::factory()->loggedAt(now()->subDays(2))->create(['message' => 'older']);
        ActivityLog::factory()->loggedAt(now())->create(['message' => 'newer']);

        $messages = ActivityLog::latestFirst()->pluck('message')->all();

        $this->assertSame(['newer', 'older'], $messages);
    }

    public function test_latest_first_breaks_ties_on_id(): void
    {
        $sameMoment = now();
        $first = ActivityLog::factory()->loggedAt($sameMoment)->create();
        $second = ActivityLog::factory()->loggedAt($sameMoment)->create();

        $ids = ActivityLog::latestFirst()->pluck('id')->all();

        $this->assertSame([$second->id, $first->id], $ids);
    }

    public function test_subject_resolves_to_the_related_model(): void
    {
        $article = Article::factory()->create();
        $log = ActivityLog::factory()->forSubject($article)->create();

        $this->assertInstanceOf(Article::class, $log->subject);
        $this->assertSame($article->id, $log->subject->id);
    }

    public function test_context_round_trips_as_an_array(): void
    {
        $log = ActivityLog::factory()->create(['context' => ['reason' => 'no content', 'attempt' => 2]]);

        $this->assertSame(['reason' => 'no content', 'attempt' => 2], $log->fresh()->context);
    }
}
