<?php

namespace Tests\Feature\Http\Controllers\Api\V1;

use App\Models\Article;
use App\Models\ArticlePublication;
use App\Models\Feed;
use App\Models\PlatformChannel;
use App\Models\Route;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Carbon;
use Tests\TestCase;

class DashboardControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_stats_returns_successful_response(): void
    {
        $this
            ->getJson('/api/v1/dashboard/stats')
            ->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'data' => [
                    'article_stats' => [
                        'articles_fetched',
                        'articles_published',
                        'published_percentage',
                    ],
                    'system_stats' => [
                        'total_feeds',
                        'active_feeds',
                        'total_platform_channels',
                        'active_platform_channels',
                        'total_routes',
                        'active_routes',
                    ],
                    'range' => ['from', 'to'],
                ],
                'message',
            ]);
    }

    public function test_stats_no_longer_exposes_named_periods(): void
    {
        $this
            ->getJson('/api/v1/dashboard/stats')
            ->assertStatus(200)
            ->assertJsonMissingPath('data.available_periods')
            ->assertJsonMissingPath('data.current_period');
    }

    public function test_stats_honours_an_explicit_from_and_to_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-05 12:00:00')]);

        $this
            ->getJson('/api/v1/dashboard/stats?from=2026-07-01&to=2026-07-31')
            ->assertStatus(200)
            ->assertJson([
                'data' => [
                    'article_stats' => ['articles_fetched' => 2],
                    'range' => ['from' => '2026-07-01', 'to' => '2026-07-31'],
                ],
            ]);
    }

    public function test_stats_defaults_to_the_current_day_without_params(): void
    {
        Carbon::setTestNow('2026-07-15 13:45:00');

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

        $this
            ->getJson('/api/v1/dashboard/stats')
            ->assertStatus(200)
            ->assertJson([
                'data' => [
                    'article_stats' => ['articles_fetched' => 1],
                    'range' => ['from' => '2026-07-15', 'to' => '2026-07-15'],
                ],
            ]);
    }

    public function test_stats_rejects_an_inverted_range(): void
    {
        $this
            ->getJson('/api/v1/dashboard/stats?from=2026-07-31&to=2026-07-01')
            ->assertStatus(422);
    }

    public function test_stats_rejects_a_malformed_date(): void
    {
        $this
            ->getJson('/api/v1/dashboard/stats?from=not-a-date&to=2026-07-01')
            ->assertStatus(422);
    }

    public function test_stats_rejects_a_from_without_a_to(): void
    {
        $this
            ->getJson('/api/v1/dashboard/stats?from=2026-07-01')
            ->assertStatus(422)
            ->assertJsonValidationErrors('to');
    }

    public function test_stats_rejects_a_to_without_a_from(): void
    {
        $this
            ->getJson('/api/v1/dashboard/stats?to=2026-07-31')
            ->assertStatus(422)
            ->assertJsonValidationErrors('from');
    }

    public function test_stats_with_sample_data(): void
    {
        $feed = Feed::factory()->create(['is_active' => true]);
        $channel = PlatformChannel::factory()->create(['is_active' => true]);
        Route::factory()->create(['is_active' => true]);

        $articles = Article::factory()->count(3)->create([
            'feed_id' => $feed->id,
            'created_at' => Carbon::parse('2026-07-10 12:00:00'),
        ]);

        ArticlePublication::factory()->create([
            'article_id' => $articles->first()->id,
            'platform_channel_id' => $channel->id,
            'published_at' => Carbon::parse('2026-07-10 13:00:00'),
        ]);

        $response = $this->getJson('/api/v1/dashboard/stats?from=2026-07-01&to=2026-07-31');

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'data' => [
                    'article_stats' => [
                        'articles_fetched' => 3,
                        'articles_published' => 1,
                    ],
                    'system_stats' => [
                        'total_feeds' => Feed::count(),
                        'total_platform_channels' => PlatformChannel::count(),
                        'total_routes' => Route::count(),
                    ],
                ],
            ]);
    }

    public function test_stats_returns_empty_data_with_no_records(): void
    {
        $this
            ->getJson('/api/v1/dashboard/stats')
            ->assertStatus(200)
            ->assertJson([
                'success' => true,
                'data' => [
                    'article_stats' => [
                        'articles_fetched' => 0,
                        'articles_published' => 0,
                        'published_percentage' => 0.0,
                    ],
                    'system_stats' => [
                        'total_feeds' => 0,
                        'active_feeds' => 0,
                        'total_platform_accounts' => 0,
                        'active_platform_accounts' => 0,
                        'total_platform_channels' => 0,
                        'active_platform_channels' => 0,
                        'total_routes' => 0,
                        'active_routes' => 0,
                    ],
                ],
            ]);
    }
}
