<?php

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

use App\Models\Feed;
use App\Models\Language;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class FeedsControllerTest extends TestCase
{
    use RefreshDatabase;

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

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'data' => [
                    'feeds',
                    'pagination',
                ],
                'message',
            ]);
    }

    public function test_index_returns_feeds_ordered_by_active_status_then_name(): void
    {
        Feed::factory()->create(['name' => 'Z Feed', 'is_active' => false]);
        Feed::factory()->create(['name' => 'A Feed', 'is_active' => true]);
        Feed::factory()->create(['name' => 'B Feed', 'is_active' => true]);

        $response = $this->getJson('/api/v1/feeds');

        $response->assertStatus(200);
        $feeds = $response->json('data.feeds');

        // First should be active feeds in alphabetical order
        $this->assertEquals('A Feed', $feeds[0]['name']);
        $this->assertTrue($feeds[0]['is_active']);
        $this->assertEquals('B Feed', $feeds[1]['name']);
        $this->assertTrue($feeds[1]['is_active']);
        // Then inactive feeds
        $this->assertEquals('Z Feed', $feeds[2]['name']);
        $this->assertFalse($feeds[2]['is_active']);
    }

    public function test_store_creates_vrt_feed_successfully(): void
    {
        $language = Language::factory()->english()->create();

        $feedData = [
            'name' => 'VRT Test Feed',
            'provider' => 'vrt',
            'language_id' => $language->id,
            'is_active' => true,
        ];

        $response = $this->postJson('/api/v1/feeds', $feedData);

        $response->assertStatus(201)
            ->assertJson([
                'success' => true,
                'message' => 'Feed created successfully!',
                'data' => [
                    'name' => 'VRT Test Feed',
                    'url' => 'https://www.vrt.be/vrtnws/en/',
                    'type' => 'website',
                    'is_active' => true,
                ],
            ]);

        $this->assertDatabaseHas('feeds', [
            'name' => 'VRT Test Feed',
            'url' => 'https://www.vrt.be/vrtnws/en/',
            'type' => 'website',
        ]);
    }

    public function test_store_creates_belga_feed_successfully(): void
    {
        $language = Language::factory()->english()->create();

        $feedData = [
            'name' => 'Belga Test Feed',
            'provider' => 'belga',
            'language_id' => $language->id,
            'is_active' => true,
        ];

        $response = $this->postJson('/api/v1/feeds', $feedData);

        $expectedUrl = config('feed.providers.belga.languages.en.url');

        $response->assertStatus(201)
            ->assertJson([
                'success' => true,
                'message' => 'Feed created successfully!',
                'data' => [
                    'name' => 'Belga Test Feed',
                    'url' => $expectedUrl,
                    'type' => 'website',
                    'is_active' => true,
                ],
            ]);

        $this->assertDatabaseHas('feeds', [
            'name' => 'Belga Test Feed',
            'url' => $expectedUrl,
            'type' => 'website',
        ]);
    }

    public function test_store_creates_guardian_feed_successfully(): void
    {
        $language = Language::factory()->english()->create();

        $feedData = [
            'name' => 'Guardian Test Feed',
            'provider' => 'guardian',
            'language_id' => $language->id,
            'is_active' => true,
        ];

        $response = $this->postJson('/api/v1/feeds', $feedData);

        $response->assertStatus(201)
            ->assertJson([
                'success' => true,
                'message' => 'Feed created successfully!',
                'data' => [
                    'name' => 'Guardian Test Feed',
                    'url' => 'https://www.theguardian.com/international/rss',
                    'type' => 'rss',
                    'is_active' => true,
                ],
            ]);

        $this->assertDatabaseHas('feeds', [
            'name' => 'Guardian Test Feed',
            'url' => 'https://www.theguardian.com/international/rss',
            'type' => 'rss',
        ]);
    }

    public function test_store_sets_default_active_status(): void
    {
        $language = Language::factory()->english()->create();

        $feedData = [
            'name' => 'Test Feed',
            'provider' => 'vrt',
            'language_id' => $language->id,
            // Not setting is_active
        ];

        $response = $this->postJson('/api/v1/feeds', $feedData);

        $response->assertStatus(201)
            ->assertJson([
                'data' => [
                    'is_active' => true, // Should default to true
                ],
            ]);
    }

    public function test_store_validates_required_fields(): void
    {
        $response = $this->postJson('/api/v1/feeds', []);

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['name', 'provider', 'language_id']);
    }

    public function test_store_rejects_invalid_provider(): void
    {
        $language = Language::factory()->create();

        $feedData = [
            'name' => 'Invalid Feed',
            'provider' => 'invalid',
            'language_id' => $language->id,
        ];

        $response = $this->postJson('/api/v1/feeds', $feedData);

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

    public function test_show_returns_feed_successfully(): void
    {
        $feed = Feed::factory()->create();

        $response = $this->getJson("/api/v1/feeds/{$feed->id}");

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'message' => 'Feed retrieved successfully.',
                'data' => [
                    'id' => $feed->id,
                    'name' => $feed->name,
                ],
            ]);
    }

    public function test_show_returns_404_for_nonexistent_feed(): void
    {
        $response = $this->getJson('/api/v1/feeds/999');

        $response->assertStatus(404);
    }

    public function test_update_modifies_feed_successfully(): void
    {
        $language = Language::factory()->create();
        $feed = Feed::factory()->language($language)->create(['name' => 'Original Name']);

        $updateData = [
            'name' => 'Updated Name',
            'url' => $feed->url,
            'type' => $feed->type,
            'language_id' => $feed->language_id,
        ];

        $response = $this->putJson("/api/v1/feeds/{$feed->id}", $updateData);

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'message' => 'Feed updated successfully!',
                'data' => [
                    'name' => 'Updated Name',
                ],
            ]);

        $this->assertDatabaseHas('feeds', [
            'id' => $feed->id,
            'name' => 'Updated Name',
        ]);
    }

    public function test_update_preserves_active_status_when_not_provided(): void
    {
        $language = Language::factory()->create();
        $feed = Feed::factory()->language($language)->create(['is_active' => false]);

        $updateData = [
            'name' => $feed->name,
            'url' => $feed->url,
            'type' => $feed->type,
            'language_id' => $feed->language_id,
            // Not providing is_active
        ];

        $response = $this->putJson("/api/v1/feeds/{$feed->id}", $updateData);

        $response->assertStatus(200)
            ->assertJson([
                'data' => [
                    'is_active' => false, // Should preserve original value
                ],
            ]);
    }

    public function test_destroy_deletes_feed_successfully(): void
    {
        $feed = Feed::factory()->create();

        $response = $this->deleteJson("/api/v1/feeds/{$feed->id}");

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'message' => 'Feed deleted successfully!',
            ]);

        $this->assertDatabaseMissing('feeds', ['id' => $feed->id]);
    }

    public function test_destroy_returns_404_for_nonexistent_feed(): void
    {
        $response = $this->deleteJson('/api/v1/feeds/999');

        $response->assertStatus(404);
    }

    public function test_toggle_activates_inactive_feed(): void
    {
        $feed = Feed::factory()->create(['is_active' => false]);

        $response = $this->postJson("/api/v1/feeds/{$feed->id}/toggle");

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'message' => 'Feed activated successfully!',
                'data' => [
                    'is_active' => true,
                ],
            ]);

        $this->assertDatabaseHas('feeds', [
            'id' => $feed->id,
            'is_active' => true,
        ]);
    }

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

        $response = $this->postJson("/api/v1/feeds/{$feed->id}/toggle");

        $response->assertStatus(200)
            ->assertJson([
                'success' => true,
                'message' => 'Feed deactivated successfully!',
                'data' => [
                    'is_active' => false,
                ],
            ]);

        $this->assertDatabaseHas('feeds', [
            'id' => $feed->id,
            'is_active' => false,
        ]);
    }

    public function test_toggle_returns_404_for_nonexistent_feed(): void
    {
        $response = $this->postJson('/api/v1/feeds/999/toggle');

        $response->assertStatus(404);
    }
}
