<?php

declare(strict_types=1);

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use cPad\Plugins\News\Models\NewsArticle;
use cPad\Plugins\News\Models\NewsCategory;

uses(RefreshDatabase::class);

it('publishes scheduled news articles whose publish time has passed', function (): void {
    $author = User::factory()->create();
    $category = NewsCategory::query()->create([
        'name' => 'Announcements',
        'slug' => 'announcements',
        'description' => 'Announcement category',
        'position' => 0,
        'is_active' => true,
    ]);

    $dueArticle = NewsArticle::query()->create([
        'title' => 'Due scheduled article',
        'slug' => 'due-scheduled-article',
        'excerpt' => 'Due now.',
        'content' => 'Body',
        'author_id' => $author->id,
        'category_id' => $category->id,
        'type' => NewsArticle::TYPE_ANNOUNCEMENT,
        'status' => 'scheduled',
        'editorial_status' => NewsArticle::EDITORIAL_STATUS_SCHEDULED,
        'published_at' => now()->subMinute(),
    ]);

    $futureArticle = NewsArticle::query()->create([
        'title' => 'Future scheduled article',
        'slug' => 'future-scheduled-article',
        'excerpt' => 'Not due yet.',
        'content' => 'Body',
        'author_id' => $author->id,
        'category_id' => $category->id,
        'type' => NewsArticle::TYPE_ANNOUNCEMENT,
        'status' => 'scheduled',
        'editorial_status' => NewsArticle::EDITORIAL_STATUS_SCHEDULED,
        'published_at' => now()->addHour(),
    ]);

    $this->artisan('news:publish-scheduled')
        ->expectsOutput(sprintf('Published News article #%d: "%s"', $dueArticle->id, $dueArticle->title))
        ->expectsOutput('Done. Published: 1, Errors: 0.')
        ->assertSuccessful();

    expect($dueArticle->fresh())
        ->editorial_status->toBe(NewsArticle::EDITORIAL_STATUS_PUBLISHED)
        ->status->toBe('published')
        ->and($futureArticle->fresh())
        ->editorial_status->toBe(NewsArticle::EDITORIAL_STATUS_SCHEDULED)
        ->status->toBe('scheduled');
});

it('supports dry run for scheduled news publishing', function (): void {
    $author = User::factory()->create();
    $category = NewsCategory::query()->create([
        'name' => 'Platform',
        'slug' => 'platform',
        'description' => 'Platform category',
        'position' => 0,
        'is_active' => true,
    ]);

    $article = NewsArticle::query()->create([
        'title' => 'Dry run article',
        'slug' => 'dry-run-article',
        'excerpt' => 'Due but not published in dry run.',
        'content' => 'Body',
        'author_id' => $author->id,
        'category_id' => $category->id,
        'type' => NewsArticle::TYPE_PLATFORM_UPDATE,
        'status' => 'scheduled',
        'editorial_status' => NewsArticle::EDITORIAL_STATUS_SCHEDULED,
        'published_at' => now()->subMinute(),
    ]);

    $this->artisan('news:publish-scheduled', ['--dry-run' => true])
        ->expectsOutput(sprintf('[dry-run] Would publish News article #%d: "%s"', $article->id, $article->title))
        ->assertSuccessful();

    expect($article->fresh())
        ->editorial_status->toBe(NewsArticle::EDITORIAL_STATUS_SCHEDULED)
        ->status->toBe('scheduled');
});