<?php

namespace App\Livewire;

use App\Events\RouteActivated;
use App\Models\Feed;
use App\Models\Keyword;
use App\Models\PlatformChannel;
use App\Models\Route;
use Illuminate\Contracts\View\View;
use Livewire\Component;

class Routes extends Component
{
    public bool $showCreateModal = false;

    public ?int $editingFeedId = null;

    public ?int $editingChannelId = null;

    // Create form
    public ?int $newFeedId = null;

    public ?int $newChannelId = null;

    public int $newPriority = 50;

    // Edit form
    public int $editPriority = 50;

    public string $editAutoApprove = '';

    // Keyword management
    public string $newKeyword = '';

    public bool $showKeywordInput = false;

    public function openCreateModal(): void
    {
        $this->showCreateModal = true;
        $this->newFeedId = null;
        $this->newChannelId = null;
        $this->newPriority = 50;
    }

    public function closeCreateModal(): void
    {
        $this->showCreateModal = false;
    }

    public function createRoute(): void
    {
        $this->validate([
            'newFeedId' => 'required|exists:feeds,id',
            'newChannelId' => 'required|exists:platform_channels,id',
            'newPriority' => 'required|integer|min:0',
        ]);

        $exists = Route::where('feed_id', $this->newFeedId)
            ->where('platform_channel_id', $this->newChannelId)
            ->exists();

        if ($exists) {
            $this->addError('newFeedId', 'This route already exists.');

            return;
        }

        Route::create([
            'feed_id' => $this->newFeedId,
            'platform_channel_id' => $this->newChannelId,
            'priority' => $this->newPriority,
            'is_active' => true,
        ]);

        RouteActivated::dispatch($this->newFeedId, $this->newChannelId);

        $this->closeCreateModal();
    }

    public function openEditModal(int $feedId, int $channelId): void
    {
        $route = Route::where('feed_id', $feedId)
            ->where('platform_channel_id', $channelId)
            ->firstOrFail();

        $this->editingFeedId = $feedId;
        $this->editingChannelId = $channelId;
        $this->editPriority = $route->priority;
        $this->editAutoApprove = $route->auto_approve === null ? '' : ($route->auto_approve ? '1' : '0');
        $this->newKeyword = '';
        $this->showKeywordInput = false;
    }

    public function closeEditModal(): void
    {
        $this->editingFeedId = null;
        $this->editingChannelId = null;
    }

    public function updateRoute(): void
    {
        if (! $this->editingFeedId || ! $this->editingChannelId) {
            return;
        }

        $this->validate([
            'editPriority' => 'required|integer|min:0',
        ]);

        $autoApprove = match ($this->editAutoApprove) {
            '1' => true,
            '0' => false,
            default => null,
        };

        Route::where('feed_id', $this->editingFeedId)
            ->where('platform_channel_id', $this->editingChannelId)
            ->update([
                'priority' => $this->editPriority,
                'auto_approve' => $autoApprove,
            ]);

        $this->closeEditModal();
    }

    public function toggle(int $feedId, int $channelId): void
    {
        $route = Route::where('feed_id', $feedId)
            ->where('platform_channel_id', $channelId)
            ->firstOrFail();

        $route->is_active = ! $route->is_active;
        $route->save();

        if ($route->is_active) {
            RouteActivated::dispatch($route->feed_id, $route->platform_channel_id);
        }
    }

    public function delete(int $feedId, int $channelId): void
    {
        // Delete associated keywords first
        Keyword::where('feed_id', $feedId)
            ->where('platform_channel_id', $channelId)
            ->delete();

        Route::where('feed_id', $feedId)
            ->where('platform_channel_id', $channelId)
            ->delete();
    }

    public function addKeyword(): void
    {
        if (! $this->editingFeedId || ! $this->editingChannelId || empty(trim($this->newKeyword))) {
            return;
        }

        Keyword::create([
            'feed_id' => $this->editingFeedId,
            'platform_channel_id' => $this->editingChannelId,
            'keyword' => trim($this->newKeyword),
            'is_active' => true,
        ]);

        $this->newKeyword = '';
        $this->showKeywordInput = false;
    }

    public function toggleKeyword(int $keywordId): void
    {
        $keyword = Keyword::findOrFail($keywordId);
        $keyword->is_active = ! $keyword->is_active;
        $keyword->save();
    }

    public function deleteKeyword(int $keywordId): void
    {
        Keyword::destroy($keywordId);
    }

    public function render(): View
    {
        $routes = Route::with(['feed', 'platformChannel.platformInstance'])
            ->orderBy('priority', 'desc')
            ->get();

        // Batch load keywords for all routes to avoid N+1 queries
        $routeKeys = $routes->map(fn ($r) => $r->feed_id.'-'.$r->platform_channel_id);
        $allKeywords = Keyword::whereIn('feed_id', $routes->pluck('feed_id'))
            ->whereIn('platform_channel_id', $routes->pluck('platform_channel_id'))
            ->get()
            ->groupBy(fn ($k) => $k->feed_id.'-'.$k->platform_channel_id);

        $routes = $routes->map(function ($route) use ($allKeywords) {
            $key = $route->feed_id.'-'.$route->platform_channel_id;
            $route->setRelation('keywords', $allKeywords->get($key, collect()));

            return $route;
        });

        $feeds = Feed::where('is_active', true)->orderBy('name')->get();
        $channels = PlatformChannel::where('is_active', true)->orderBy('name')->get();

        $editingRoute = null;
        $editingKeywords = collect();

        if ($this->editingFeedId && $this->editingChannelId) {
            $editingRoute = Route::with(['feed', 'platformChannel.platformInstance'])
                ->where('feed_id', $this->editingFeedId)
                ->where('platform_channel_id', $this->editingChannelId)
                ->first();

            $editingKeywords = Keyword::where('feed_id', $this->editingFeedId)
                ->where('platform_channel_id', $this->editingChannelId)
                ->get();
        }

        return view('livewire.routes', [
            'routes' => $routes,
            'feeds' => $feeds,
            'channels' => $channels,
            'editingRoute' => $editingRoute,
            'editingKeywords' => $editingKeywords,
        ])->layout('layouts.app');
    }
}
