<?php

declare(strict_types=1);

namespace App\Framework\Console\Components;

use App\Framework\Console\HistoryTab;
use App\Framework\Console\TuiView;

/**
 * Manages the state of the Terminal User Interface
 */
final class TuiState
{
    private array $categories = [];

    private int $selectedCategory = 0;

    private int $selectedCommand = 0;

    private TuiView $currentView = TuiView::CATEGORIES;

    private bool $running = false;

    // Search state
    private string $searchQuery = '';

    private array $searchResults = [];

    private int $selectedSearchResult = 0;

    // History state
    private int $selectedHistoryItem = 0;

    private HistoryTab $historyTab = HistoryTab::RECENT;

    // Form state
    private ?object $selectedCommandForForm = null;

    private bool $formMode = false;

    public function __construct()
    {
    }

    // Categories
    public function setCategories(array $categories): void
    {
        $this->categories = $categories;
    }

    public function getCategories(): array
    {
        return $this->categories;
    }

    public function getSelectedCategory(): int
    {
        return $this->selectedCategory;
    }

    public function setSelectedCategory(int $index): void
    {
        $this->selectedCategory = max(0, min($index, count($this->categories) - 1));
    }

    public function getCurrentCategory(): ?array
    {
        return $this->categories[$this->selectedCategory] ?? null;
    }

    // Commands
    public function getSelectedCommand(): int
    {
        return $this->selectedCommand;
    }

    public function setSelectedCommand(int $index): void
    {
        $category = $this->getCurrentCategory();
        if ($category) {
            $maxIndex = count($category['commands']) - 1;
            $this->selectedCommand = max(0, min($index, $maxIndex));
        }
    }

    public function getCurrentCommand(): ?object
    {
        $category = $this->getCurrentCategory();

        return $category['commands'][$this->selectedCommand] ?? null;
    }

    // View management
    public function getCurrentView(): TuiView
    {
        return $this->currentView;
    }

    public function setCurrentView(TuiView $view): void
    {
        $this->currentView = $view;
    }

    public function isRunning(): bool
    {
        return $this->running;
    }

    public function setRunning(bool $running): void
    {
        $this->running = $running;
    }

    // Search
    public function getSearchQuery(): string
    {
        return $this->searchQuery;
    }

    public function setSearchQuery(string $query): void
    {
        $this->searchQuery = $query;
    }

    public function getSearchResults(): array
    {
        return $this->searchResults;
    }

    public function setSearchResults(array $results): void
    {
        $this->searchResults = $results;
        $this->selectedSearchResult = 0;
    }

    public function getSelectedSearchResult(): int
    {
        return $this->selectedSearchResult;
    }

    public function setSelectedSearchResult(int $index): void
    {
        $this->selectedSearchResult = max(0, min($index, count($this->searchResults) - 1));
    }

    public function getCurrentSearchResult(): ?object
    {
        return $this->searchResults[$this->selectedSearchResult] ?? null;
    }

    // History
    public function getSelectedHistoryItem(): int
    {
        return $this->selectedHistoryItem;
    }

    public function setSelectedHistoryItem(int $index): void
    {
        $this->selectedHistoryItem = max(0, $index);
    }

    public function getHistoryTab(): HistoryTab
    {
        return $this->historyTab;
    }

    public function setHistoryTab(HistoryTab $tab): void
    {
        $this->historyTab = $tab;
        $this->selectedHistoryItem = 0;
    }

    // Form
    public function getSelectedCommandForForm(): ?object
    {
        return $this->selectedCommandForForm;
    }

    public function setSelectedCommandForForm(?object $command): void
    {
        $this->selectedCommandForForm = $command;
    }

    public function isFormMode(): bool
    {
        return $this->formMode;
    }

    public function setFormMode(bool $formMode): void
    {
        $this->formMode = $formMode;
    }

    // Navigation helpers
    public function navigateUp(): void
    {
        match ($this->currentView) {
            TuiView::CATEGORIES => $this->setSelectedCategory($this->selectedCategory - 1),
            TuiView::COMMANDS => $this->setSelectedCommand($this->selectedCommand - 1),
            TuiView::SEARCH => $this->setSelectedSearchResult($this->selectedSearchResult - 1),
            TuiView::HISTORY => $this->setSelectedHistoryItem($this->selectedHistoryItem - 1),
            default => null
        };
    }

    public function navigateDown(): void
    {
        match ($this->currentView) {
            TuiView::CATEGORIES => $this->setSelectedCategory($this->selectedCategory + 1),
            TuiView::COMMANDS => $this->setSelectedCommand($this->selectedCommand + 1),
            TuiView::SEARCH => $this->setSelectedSearchResult($this->selectedSearchResult + 1),
            TuiView::HISTORY => $this->setSelectedHistoryItem($this->selectedHistoryItem + 1),
            default => null
        };
    }

    public function resetSearchState(): void
    {
        $this->searchQuery = '';
        $this->searchResults = [];
        $this->selectedSearchResult = 0;
    }

    public function resetFormState(): void
    {
        $this->selectedCommandForForm = null;
        $this->formMode = false;
    }

    // Workflow-related state
    private array $workflows = [];

    private int $selectedWorkflow = 0;

    private bool $showWorkflows = false;

    private array $workflowProgress = [];

    /**
     * Set available workflows
     */
    public function setWorkflows(array $workflows): void
    {
        $this->workflows = $workflows;
    }

    /**
     * Get available workflows
     */
    public function getWorkflows(): array
    {
        return $this->workflows;
    }

    /**
     * Set selected workflow
     */
    public function setSelectedWorkflow(int $index): void
    {
        $this->selectedWorkflow = max(0, min($index, count($this->workflows) - 1));
    }

    /**
     * Get selected workflow
     */
    public function getSelectedWorkflow(): int
    {
        return $this->selectedWorkflow;
    }

    /**
     * Get current workflow
     */
    public function getCurrentWorkflow(): ?array
    {
        return $this->workflows[$this->selectedWorkflow] ?? null;
    }

    /**
     * Set workflow visibility
     */
    public function setShowWorkflows(bool $show): void
    {
        $this->showWorkflows = $show;
    }

    /**
     * Check if workflows should be shown
     */
    public function shouldShowWorkflows(): bool
    {
        return $this->showWorkflows;
    }

    /**
     * Set workflow progress
     */
    public function setWorkflowProgress(string $workflowName, array $progress): void
    {
        $this->workflowProgress[$workflowName] = $progress;
    }

    /**
     * Get workflow progress
     */
    public function getWorkflowProgress(string $workflowName): array
    {
        return $this->workflowProgress[$workflowName] ?? [];
    }

    /**
     * Reset workflow state
     */
    public function resetWorkflowState(): void
    {
        $this->selectedWorkflow = 0;
        $this->showWorkflows = false;
        $this->workflowProgress = [];
    }
}
