<?php

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

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

class RoutingControllerTest extends TestCase
{
    use RefreshDatabase;

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

        // Create unique feeds and channels for this test
        $feeds = Feed::factory()->count(3)->create(['language_id' => $language->id]);
        $channels = PlatformChannel::factory()->count(3)->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        foreach ($feeds as $index => $feed) {
            Route::factory()->create([
                'feed_id' => $feed->id,
                'platform_channel_id' => $channels[$index]->id,
            ]);
        }

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

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'message',
                'data' => [
                    '*' => [
                        'feed_id',
                        'platform_channel_id',
                        'is_active',
                        'priority',
                        'created_at',
                        'updated_at',
                    ],
                ],
            ])
            ->assertJson([
                'success' => true,
                'message' => 'Routing configurations retrieved successfully.',
            ]);
    }

    public function test_store_creates_routing_configuration_successfully(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $data = [
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => true,
            'priority' => 5,
        ];

        $response = $this->postJson('/api/v1/routing', $data);

        $response->assertStatus(201)
            ->assertJsonStructure([
                'success',
                'message',
                'data' => [
                    'feed_id',
                    'platform_channel_id',
                    'is_active',
                    'priority',
                    'created_at',
                    'updated_at',
                ],
            ])
            ->assertJson([
                'success' => true,
                'message' => 'Routing configuration created successfully!',
            ]);

        $this->assertDatabaseHas('routes', [
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => true,
            'priority' => 5,
        ]);
    }

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

        $response->assertStatus(422)
            ->assertJsonValidationErrors(['feed_id', 'platform_channel_id']);
    }

    public function test_store_validates_feed_exists(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $data = [
            'feed_id' => 999,
            'platform_channel_id' => $channel->id,
        ];

        $response = $this->postJson('/api/v1/routing', $data);

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

    public function test_store_validates_platform_channel_exists(): void
    {
        $language = Language::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);

        $data = [
            'feed_id' => $feed->id,
            'platform_channel_id' => 999,
        ];

        $response = $this->postJson('/api/v1/routing', $data);

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

    public function test_show_returns_routing_configuration_successfully(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $route = Route::factory()->create([
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
        ]);

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

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'message',
                'data' => [
                    'feed_id',
                    'platform_channel_id',
                    'is_active',
                    'priority',
                    'created_at',
                    'updated_at',
                ],
            ])
            ->assertJson([
                'success' => true,
                'message' => 'Routing configuration retrieved successfully.',
            ]);
    }

    public function test_show_returns_404_for_nonexistent_routing(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

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

        $response->assertStatus(404)
            ->assertJson([
                'success' => false,
                'message' => 'Routing configuration not found.',
            ]);
    }

    public function test_update_modifies_routing_configuration_successfully(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $route = Route::factory()->create([
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => true,
            'priority' => 1,
        ]);

        $updateData = [
            'is_active' => false,
            'priority' => 10,
        ];

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

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

        $this->assertDatabaseHas('routes', [
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => false,
            'priority' => 10,
        ]);
    }

    public function test_update_returns_404_for_nonexistent_routing(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $response = $this->putJson("/api/v1/routing/{$feed->id}/{$channel->id}", [
            'is_active' => false,
        ]);

        $response->assertStatus(404)
            ->assertJson([
                'success' => false,
                'message' => 'Routing configuration not found.',
            ]);
    }

    public function test_destroy_deletes_routing_configuration_successfully(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $route = Route::factory()->create([
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
        ]);

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

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

        $this->assertDatabaseMissing('routes', [
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
        ]);
    }

    public function test_destroy_returns_404_for_nonexistent_routing(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

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

        $response->assertStatus(404)
            ->assertJson([
                'success' => false,
                'message' => 'Routing configuration not found.',
            ]);
    }

    public function test_toggle_activates_inactive_routing(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $route = Route::factory()->create([
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => false,
        ]);

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

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

        $this->assertDatabaseHas('routes', [
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => true,
        ]);
    }

    public function test_toggle_deactivates_active_routing(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

        $route = Route::factory()->create([
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => true,
        ]);

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

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

        $this->assertDatabaseHas('routes', [
            'feed_id' => $feed->id,
            'platform_channel_id' => $channel->id,
            'is_active' => false,
        ]);
    }

    public function test_toggle_returns_404_for_nonexistent_routing(): void
    {
        $language = Language::factory()->create();
        $instance = PlatformInstance::factory()->create();
        $feed = Feed::factory()->create(['language_id' => $language->id]);
        $channel = PlatformChannel::factory()->create([
            'platform_instance_id' => $instance->id,
            'language_id' => $language->id,
        ]);

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

        $response->assertStatus(404)
            ->assertJson([
                'success' => false,
                'message' => 'Routing configuration not found.',
            ]);
    }
}
