<?php

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

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

class KeywordsControllerTest extends TestCase
{
    use RefreshDatabase;

    protected Feed $feed;

    protected PlatformChannel $channel;

    protected Route $route;

    protected function setUp(): void
    {
        parent::setUp();

        $this->feed = Feed::factory()->create();
        $this->channel = PlatformChannel::factory()->create();

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

    public function test_can_get_keywords_for_route(): void
    {
        $keyword = Keyword::factory()->create([
            'feed_id' => $this->feed->id,
            'platform_channel_id' => $this->channel->id,
            'keyword' => 'test keyword',
            'is_active' => true,
        ]);

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

        $response->assertStatus(200)
            ->assertJsonStructure([
                'success',
                'data' => [
                    '*' => [
                        'id',
                        'keyword',
                        'is_active',
                        'feed_id',
                        'platform_channel_id',
                    ],
                ],
            ])
            ->assertJsonPath('data.0.keyword', 'test keyword');
    }

    public function test_can_create_keyword_for_route(): void
    {
        $keywordData = [
            'keyword' => 'new keyword',
            'is_active' => true,
        ];

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

        $response->assertStatus(201)
            ->assertJsonStructure([
                'success',
                'data' => [
                    'id',
                    'keyword',
                    'is_active',
                    'feed_id',
                    'platform_channel_id',
                ],
            ])
            ->assertJsonPath('data.keyword', 'new keyword')
            ->assertJsonPath('data.is_active', true);

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

    public function test_cannot_create_duplicate_keyword_for_route(): void
    {
        Keyword::factory()->create([
            'feed_id' => $this->feed->id,
            'platform_channel_id' => $this->channel->id,
            'keyword' => 'duplicate keyword',
        ]);

        $response = $this->postJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords", [
            'keyword' => 'duplicate keyword',
        ]);

        $response->assertStatus(409)
            ->assertJsonPath('success', false)
            ->assertJsonPath('message', 'Keyword already exists for this route.');
    }

    public function test_can_update_keyword(): void
    {
        /** @var Keyword $keyword */
        $keyword = Keyword::factory()->create([
            'feed_id' => $this->feed->id,
            'platform_channel_id' => $this->channel->id,
            'is_active' => true,
        ]);

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

        $response->assertStatus(200)
            ->assertJsonPath('data.is_active', false);

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

    public function test_can_delete_keyword(): void
    {
        /** @var Keyword $keyword */
        $keyword = Keyword::factory()->create([
            'feed_id' => $this->feed->id,
            'platform_channel_id' => $this->channel->id,
        ]);

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

        $response->assertStatus(200);

        $this->assertDatabaseMissing('keywords', [
            'id' => $keyword->id,
        ]);
    }

    public function test_can_toggle_keyword(): void
    {
        /** @var Keyword $keyword */
        $keyword = Keyword::factory()->create([
            'feed_id' => $this->feed->id,
            'platform_channel_id' => $this->channel->id,
            'is_active' => true,
        ]);

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

        $response->assertStatus(200)
            ->assertJsonPath('data.is_active', false);

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

    public function test_cannot_access_keyword_from_different_route(): void
    {
        $otherFeed = Feed::factory()->create();
        $otherChannel = PlatformChannel::factory()->create();

        /** @var Keyword $keyword */
        $keyword = Keyword::factory()->create([
            'feed_id' => $otherFeed->id,
            'platform_channel_id' => $otherChannel->id,
        ]);

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

        $response->assertStatus(404)
            ->assertJsonPath('message', 'Keyword not found for this route.');
    }

    public function test_validates_required_fields(): void
    {
        $response = $this->postJson("/api/v1/routing/{$this->feed->id}/{$this->channel->id}/keywords", []);

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