<?php

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

use App\Models\Setting;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class SettingsControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_index_returns_current_settings(): void
    {
        $response = $this->getJson('/api/v1/settings');

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'data' => [
                    'article_processing_enabled',
                    'publishing_approvals_enabled',
                    'article_publishing_interval',
                ],
                'message',
            ])
            ->assertJson([
                'success' => true,
                'message' => 'Settings retrieved successfully.',
            ]);
    }

    public function test_update_modifies_article_processing_setting(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'article_processing_enabled' => false,
        ]);

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'message' => 'Settings updated successfully.',
                'data' => [
                    'article_processing_enabled' => false,
                ],
            ]);
    }

    public function test_update_modifies_publishing_approvals_setting(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'publishing_approvals_enabled' => true,
        ]);

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'message' => 'Settings updated successfully.',
                'data' => [
                    'publishing_approvals_enabled' => true,
                ],
            ]);
    }

    public function test_update_validates_boolean_values(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'article_processing_enabled' => 'not-a-boolean',
            'publishing_approvals_enabled' => 'also-not-boolean',
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors([
                'article_processing_enabled',
                'publishing_approvals_enabled',
            ]);
    }

    public function test_update_accepts_partial_updates(): void
    {
        // Update only one setting
        $response = $this->putJson('/api/v1/settings', [
            'article_processing_enabled' => true,
        ]);

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'data' => [
                    'article_processing_enabled' => true,
                ],
            ]);

        // Should still have structure for all settings
        $response->assertJsonStructure([
            'data' => [
                'article_processing_enabled',
                'publishing_approvals_enabled',
                'article_publishing_interval',
            ],
        ]);
    }

    public function test_index_returns_article_publishing_interval(): void
    {
        $response = $this->getJson('/api/v1/settings');

        $response->assertStatus(200)
            ->assertJsonStructure([
                'data' => [
                    'article_publishing_interval',
                ],
            ])
            ->assertJsonPath('data.article_publishing_interval', 5);
    }

    public function test_index_returns_daily_publish_cap(): void
    {
        $response = $this->getJson('/api/v1/settings');

        $response->assertStatus(200)
            ->assertJsonStructure([
                'data' => [
                    'daily_publish_cap',
                ],
            ])
            ->assertJsonPath('data.daily_publish_cap', 0);
    }

    public function test_update_accepts_valid_daily_publish_cap(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'daily_publish_cap' => 30,
        ]);

        $response->assertStatus(200)
            ->assertJsonPath('data.daily_publish_cap', 30);

        $this->assertSame(30, Setting::getDailyPublishCap());
    }

    public function test_update_rejects_negative_daily_publish_cap(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'daily_publish_cap' => -1,
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['daily_publish_cap']);
    }

    public function test_update_accepts_valid_article_publishing_interval(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'article_publishing_interval' => 15,
        ]);

        $response->assertStatus(200)
            ->assertJsonPath('data.article_publishing_interval', 15);

        $this->assertSame(15, Setting::getArticlePublishingInterval());
    }

    public function test_update_rejects_negative_article_publishing_interval(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'article_publishing_interval' => -5,
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['article_publishing_interval']);
    }

    public function test_update_rejects_non_integer_article_publishing_interval(): void
    {
        $response = $this->putJson('/api/v1/settings', [
            'article_publishing_interval' => 'abc',
        ]);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['article_publishing_interval']);
    }
}
