<?php

namespace App\Livewire;

use App\Actions\CreateFeedAction;
use App\Models\Feed;
use App\Models\Language;
use Illuminate\Contracts\View\View;
use InvalidArgumentException;
use Livewire\Component;

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

    public string $newName = '';

    public string $newProvider = '';

    public ?int $newLanguageId = null;

    public string $newDescription = '';

    public ?int $editingFeedId = null;

    public string $editName = '';

    public string $editDescription = '';

    public function toggle(int $feedId): void
    {
        $feed = Feed::findOrFail($feedId);
        $feed->is_active = ! $feed->is_active;
        $feed->save();
    }

    public function openCreateModal(): void
    {
        $this->reset(['newName', 'newProvider', 'newLanguageId', 'newDescription']);
        $this->resetErrorBag();
        $this->showCreateModal = true;
    }

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

    public function createFeed(CreateFeedAction $action): void
    {
        $providers = array_keys($this->activeProviders());

        $this->validate([
            'newName' => 'required|string|max:255',
            'newProvider' => ['required', 'string', 'in:'.implode(',', $providers)],
            'newLanguageId' => 'required|integer|exists:languages,id',
        ]);

        try {
            $action->execute(
                $this->newName,
                $this->newProvider,
                $this->newLanguageId,
                // Blade textarea binds an empty string when blank; the action expects null for "no description".
                $this->newDescription !== '' ? $this->newDescription : null,
            );
        } catch (InvalidArgumentException $e) {
            $this->addError('newProvider', 'This provider is not available for the selected language.');

            return;
        }

        $this->closeCreateModal();
    }

    public function openEditModal(int $feedId): void
    {
        $feed = Feed::findOrFail($feedId);

        $this->resetErrorBag();
        $this->editingFeedId = $feedId;
        $this->editName = $feed->name;
        $this->editDescription = $feed->description ?? '';
    }

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

    // Provider and language are deliberately not editable: CreateFeedAction derives the unique
    // feeds.url from that pair, so changing either re-points the feed and orphans its articles.
    public function updateFeed(): void
    {
        if ($this->editingFeedId === null) {
            return;
        }

        $this->validate([
            'editName' => 'required|string|max:255',
        ]);

        Feed::findOrFail($this->editingFeedId)->update([
            'name' => $this->editName,
            'description' => $this->editDescription !== '' ? $this->editDescription : null,
        ]);

        $this->closeEditModal();
    }

    /**
     * @return array<string, array<string, mixed>>
     */
    private function activeProviders(): array
    {
        /** @var array<string, array<string, mixed>> $providers */
        $providers = config('feed.providers', []);

        return array_filter($providers, fn (array $provider): bool => ($provider['is_active'] ?? false) === true);
    }

    public function render(): View
    {
        $feeds = Feed::orderBy('name')->get();

        return view('livewire.feeds', [
            'feeds' => $feeds,
            'providers' => $this->activeProviders(),
            'languages' => Language::where('is_active', true)->orderBy('name')->get(),
            'editingFeed' => $this->editingFeedId !== null
                ? Feed::with('language')->find($this->editingFeedId)
                : null,
        ])->layout('layouts.app');
    }
}
