<?php

namespace Tests\Unit\Services;

use App\Models\Article;
use App\Models\ArticlePublication;
use App\Services\DashboardStatsService;
use App\Support\DateRange;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class DashboardStatsServiceTest extends TestCase
{
    use RefreshDatabase;

    private function service(): DashboardStatsService
    {
        return new DashboardStatsService;
    }

    public function test_it_counts_articles_fetched_within_the_range(): void
    {
        Article::factory()->count(2)->create(['created_at' => Carbon::parse('2026-07-10 12:00:00')]);
        Article::factory()->create(['created_at' => Carbon::parse('2026-08-01 12:00:00')]);

        $stats = $this->service()->getStats(new DateRange(
            Carbon::parse('2026-07-01 00:00:00'),
            Carbon::parse('2026-07-31 23:59:59'),
        ));

        $this->assertSame(2, $stats['articles_fetched']);
    }

    public function test_it_counts_articles_published_within_the_range(): void
    {
        ArticlePublication::factory()->create(['published_at' => Carbon::parse('2026-07-10 12:00:00')]);
        ArticlePublication::factory()->create(['published_at' => Carbon::parse('2026-08-01 12:00:00')]);

        $stats = $this->service()->getStats(new DateRange(
            Carbon::parse('2026-07-01 00:00:00'),
            Carbon::parse('2026-07-31 23:59:59'),
        ));

        $this->assertSame(1, $stats['articles_published']);
    }

    public function test_it_calculates_the_published_percentage(): void
    {
        $range = new DateRange(
            Carbon::parse('2026-07-01 00:00:00'),
            Carbon::parse('2026-07-31 23:59:59'),
        );

        Article::factory()->count(4)->create(['created_at' => Carbon::parse('2026-07-10 12:00:00')]);
        ArticlePublication::factory()->create(['published_at' => Carbon::parse('2026-07-10 12:00:00')]);

        $stats = $this->service()->getStats($range);

        $this->assertSame(25.0, $stats['published_percentage']);
    }

    public function test_it_reports_a_zero_percentage_when_nothing_was_fetched(): void
    {
        $stats = $this->service()->getStats(DateRange::preset('all'));

        $this->assertSame(0, $stats['articles_fetched']);
        $this->assertSame(0.0, $stats['published_percentage']);
    }

    public function test_it_excludes_records_outside_the_range_entirely(): void
    {
        Article::factory()->create(['created_at' => Carbon::parse('2026-06-30 23:59:59')]);
        Article::factory()->create(['created_at' => Carbon::parse('2026-08-01 00:00:00')]);

        $stats = $this->service()->getStats(new DateRange(
            Carbon::parse('2026-07-01 00:00:00'),
            Carbon::parse('2026-07-31 23:59:59'),
        ));

        $this->assertSame(0, $stats['articles_fetched']);
    }

    public function test_it_counts_everything_for_the_all_preset(): void
    {
        Carbon::setTestNow('2026-07-15 12:00:00');

        Article::factory()->create(['created_at' => Carbon::parse('2020-01-01 00:00:00')]);
        Article::factory()->create(['created_at' => Carbon::parse('2026-07-15 11:00:00')]);

        $stats = $this->service()->getStats(DateRange::preset('all'));

        $this->assertSame(2, $stats['articles_fetched']);
    }
}
