<?php

declare(strict_types=1);

namespace App\Framework\Console\Components;

use App\Framework\Console\CommandHistory;
use App\Framework\Console\ConsoleColor;
use App\Framework\Console\ConsoleOutputInterface;
use App\Framework\Console\HistoryTab;
use App\Framework\Console\Screen\CursorControlCode;
use App\Framework\Console\Screen\ScreenControlCode;
use App\Framework\Console\TuiView;
use App\Framework\Discovery\ValueObjects\DiscoveredAttribute;

/**
 * Handles all rendering and display logic for the TUI
 */
final readonly class TuiRenderer
{
    public function __construct(
        private ConsoleOutputInterface $output
    ) {
    }

    /**
     * Render the current view based on state
     */
    public function render(TuiState $state, CommandHistory $history): void
    {
        $this->clearScreen();
        $this->renderHeader();

        match ($state->getCurrentView()) {
            TuiView::CATEGORIES => $this->renderCategories($state),
            TuiView::COMMANDS => $this->renderCommands($state),
            TuiView::SEARCH => $this->renderSearch($state),
            TuiView::HISTORY => $this->renderHistory($state, $history),
            TuiView::FORM => $this->renderForm($state),
            TuiView::DASHBOARD => $this->renderDashboard($state),
            TuiView::HELP => $this->renderHelp($state),
        };
    }

    /**
     * Clear screen and reset cursor
     */
    private function clearScreen(): void
    {
        $this->output->write(ScreenControlCode::CLEAR_ALL->format());
        $this->output->write(CursorControlCode::POSITION->format(1, 1));
    }

    /**
     * Render header with title
     */
    private function renderHeader(): void
    {
        $this->output->writeLine('');
        $this->output->writeLine('🚀 Interactive Console - Modern TUI', ConsoleColor::BRIGHT_CYAN);
        $this->output->writeLine(str_repeat('═', 60), ConsoleColor::GRAY);
        $this->output->writeLine('');
    }

    /**
     * Render categories view
     */
    private function renderCategories(TuiState $state): void
    {
        $this->output->writeLine('📂 Select Category:', ConsoleColor::BRIGHT_YELLOW);
        $this->output->writeLine('');

        $categories = $state->getCategories();
        foreach ($categories as $index => $category) {
            $isSelected = $index === $state->getSelectedCategory();
            $this->renderCategoryItem($category, $isSelected);
        }

        $this->output->newLine();
        $this->renderNavigationBar([
            "↑/↓: Navigate",
            "Enter: Select",
            "/: Search",
            "R: History",
            "D: Dashboard",
            "F1: Help",
            "Q: Quit",
        ]);
    }

    /**
     * Render a category item
     */
    private function renderCategoryItem(array $category, bool $isSelected): void
    {
        $icon = $category['icon'] ?? '📁';
        $name = $category['name'];
        $count = count($category['commands']);

        $prefix = $isSelected ? '▶ ' : '  ';
        $color = $isSelected ? ConsoleColor::BRIGHT_WHITE : ConsoleColor::WHITE;

        $this->output->writeLine(
            "{$prefix}{$icon} {$name} ({$count} commands)",
            $color
        );
    }

    /**
     * Render commands view
     */
    private function renderCommands(TuiState $state): void
    {
        $category = $state->getCurrentCategory();
        if (! $category) {
            return;
        }

        $icon = $category['icon'] ?? '📁';
        $this->output->writeLine("📂 {$icon} {$category['name']} Commands:", ConsoleColor::BRIGHT_YELLOW);
        $this->output->writeLine('');

        foreach ($category['commands'] as $index => $command) {
            $isSelected = $index === $state->getSelectedCommand();
            $this->renderCommandItem($command, $isSelected);
        }

        $this->output->newLine();
        $this->renderNavigationBar([
            "↑/↓: Navigate",
            "Enter: Execute",
            "Space: Parameters",
            "H: Help",
            "V: Validate",
            "/: Search",
            "R: History",
            "←: Back",
            "Q: Quit",
        ]);
    }

    /**
     * Render a command item
     */
    private function renderCommandItem(object $command, bool $isSelected): void
    {
        $prefix = $isSelected ? '▶ ' : '  ';
        $color = $isSelected ? ConsoleColor::BRIGHT_WHITE : ConsoleColor::WHITE;

        // Handle DiscoveredAttribute objects
        if ($command instanceof DiscoveredAttribute) {
            $attribute = $command->createAttributeInstance();
            if ($attribute === null) {
                return;
            }
            $commandName = $attribute->name;
            $commandDescription = $attribute->description ?? '';
        } else {
            // Fallback for legacy objects
            $commandName = $command->name ?? 'Unknown Command';
            $commandDescription = $command->description ?? '';
        }

        $this->output->writeLine("{$prefix}⚡ {$commandName}", $color);

        if (! empty($commandDescription)) {
            $descColor = ConsoleColor::GRAY;
            $this->output->writeLine("    {$commandDescription}", $descColor);
        }
    }

    /**
     * Render search view
     */
    private function renderSearch(TuiState $state): void
    {
        $this->output->writeLine('🔍 Search Commands:', ConsoleColor::BRIGHT_YELLOW);
        $this->output->writeLine('');

        // Search box
        $query = $state->getSearchQuery();
        $this->output->writeLine("Search: {$query}_", ConsoleColor::BRIGHT_WHITE);
        $this->output->writeLine('');

        // Results
        $results = $state->getSearchResults();
        if (empty($results)) {
            if (! empty($query)) {
                $this->output->writeLine('No commands found matching your search.', ConsoleColor::YELLOW);
            } else {
                $this->output->writeLine('Start typing to search commands...', ConsoleColor::GRAY);
            }
        } else {
            $resultCount = count($results);
            $this->output->writeLine("Found {$resultCount} result(s):", ConsoleColor::WHITE);
            $this->output->writeLine('');

            foreach ($results as $index => $command) {
                $isSelected = $index === $state->getSelectedSearchResult();
                $this->renderCommandItem($command, $isSelected);
            }

            $current = $state->getSelectedSearchResult() + 1;
            $total = count($results);
            if ($total > 1) {
                $this->output->writeLine('');
                $this->output->writeLine(" Showing result $current of $total", ConsoleColor::GRAY);
            }
        }

        // Navigation shortcuts
        $shortcuts = [
            'Type: Search',
            'Enter: Execute',
            'Space: Parameters',
            'H: Help',
            'V: Validate',
            'R: History',
            'Esc: Back',
            'D: Dashboard',
            'Q: Exit',
        ];
        $this->renderNavigationBar($shortcuts);
    }

    /**
     * Render history view
     */
    private function renderHistory(TuiState $state, CommandHistory $history): void
    {
        $this->output->writeLine('📚 Command History:', ConsoleColor::BRIGHT_YELLOW);
        $this->output->writeLine('');

        // Tab navigation
        $this->renderHistoryTabs($state->getHistoryTab());

        // History items
        $items = $this->getHistoryItems($state->getHistoryTab(), $history);

        if (empty($items)) {
            $this->output->writeLine('No history available.', ConsoleColor::YELLOW);
        } else {
            foreach ($items as $index => $item) {
                $isSelected = $index === $state->getSelectedHistoryItem();
                $this->renderHistoryItem($item, $isSelected, $history);
            }
        }

        $this->output->writeLine('');
        $this->renderNavigationHelp([
            "↑/↓: Navigate",
            "←/→: Switch tabs",
            "Enter: Execute command",
            "Space: Parameters",
            "H: Help",
            "V: Validate",
            "F: Toggle favorite",
            "C: Clear history",
            "/: Search",
            "Q: Quit",
        ]);
    }

    /**
     * Render history tabs
     */
    private function renderHistoryTabs(HistoryTab $activeTab): void
    {
        $tabs = [
            HistoryTab::RECENT,
            HistoryTab::FREQUENT,
            HistoryTab::FAVORITES,
        ];

        $tabDisplay = [];
        foreach ($tabs as $tab) {
            $isActive = $tab === $activeTab;
            $color = $isActive ? ConsoleColor::BRIGHT_WHITE : ConsoleColor::GRAY;
            $prefix = $isActive ? '[' : ' ';
            $suffix = $isActive ? ']' : ' ';

            $tabDisplay[] = [
                'text' => "{$prefix}{$tab->getIcon()} {$tab->getTitle()}{$suffix}",
                'color' => $color,
            ];
        }

        foreach ($tabDisplay as $tab) {
            $this->output->write($tab['text'], $tab['color']);
        }
        $this->output->writeLine('');
        $this->output->writeLine('');
    }

    /**
     * Render history item
     */
    private function renderHistoryItem(array $item, bool $isSelected, CommandHistory $history): void
    {
        $prefix = $isSelected ? '▶ ' : '  ';
        $color = $isSelected ? ConsoleColor::BRIGHT_WHITE : ConsoleColor::WHITE;

        $command = $item['command'];
        $isFavorite = $history->isFavorite($command);
        $favoriteIcon = $isFavorite ? '⭐' : '  ';

        $this->output->writeLine("{$prefix}{$favoriteIcon} ⚡ {$command}", $color);

        // Additional info based on type
        $infoColor = ConsoleColor::GRAY;
        if (isset($item['count'])) {
            $this->output->writeLine("    Used {$item['count']} times", $infoColor);
        }
        if (isset($item['timestamp'])) {
            $timeAgo = $this->timeAgo($item['timestamp']);
            $this->output->writeLine("    {$timeAgo}", $infoColor);
        }
    }

    /**
     * Render form view placeholder
     */
    private function renderForm(TuiState $state): void
    {
        $this->output->writeLine('📝 Interactive Form', ConsoleColor::BRIGHT_YELLOW);
        $this->output->writeLine('Form functionality handled by InteractiveForm class', ConsoleColor::GRAY);
    }

    /**
     * Render dashboard view
     */
    private function renderDashboard(TuiState $state): void
    {
        $this->output->writeLine('📊 System Dashboard', ConsoleColor::BRIGHT_YELLOW);
        $this->output->writeLine('');
        $this->output->writeLine('Console system status and metrics', ConsoleColor::WHITE);
        $this->output->writeLine('');

        $this->renderNavigationBar([
            "Categories: C",
            "Search: /",
            "History: R",
            "Help: F1",
            "Back: Esc",
            "Quit: Q",
        ]);
    }

    /**
     * Render help view
     */
    private function renderHelp(TuiState $state): void
    {
        $this->output->writeLine('❓ Help & Shortcuts', ConsoleColor::BRIGHT_YELLOW);
        $this->output->writeLine('');

        $helpSections = [
            'Navigation' => [
                '↑/↓ Arrow Keys' => 'Navigate up and down in lists',
                '←/→ Arrow Keys' => 'Navigate left/right, switch tabs',
                'Enter' => 'Execute selected command',
                'Esc' => 'Go back to previous view',
            ],
            'Commands' => [
                'Space' => 'Open interactive parameter form',
                'H' => 'Show detailed command help',
                'V' => 'Validate command signature',
                'F1' => 'Show all commands help overview',
            ],
            'Views' => [
                '/' => 'Search commands',
                'R' => 'Command history',
                'D' => 'Dashboard',
                'C' => 'Categories (from other views)',
            ],
            'History' => [
                'F' => 'Toggle command as favorite',
                'C' => 'Clear command history',
            ],
        ];

        foreach ($helpSections as $section => $items) {
            $this->output->writeLine($section . ':', ConsoleColor::BRIGHT_WHITE);
            foreach ($items as $key => $description) {
                $this->output->writeLine("  {$key} - {$description}", ConsoleColor::WHITE);
            }
            $this->output->writeLine('');
        }

        $this->renderNavigationBar([
            "Back: Esc",
            "Categories: C",
            "Quit: Q",
        ]);
    }

    /**
     * Render navigation bar
     */
    private function renderNavigationBar(array $items): void
    {
        $this->output->writeLine(str_repeat('─', 60), ConsoleColor::GRAY);
        $this->output->writeLine(implode(' | ', $items), ConsoleColor::BRIGHT_BLUE);
    }

    /**
     * Render navigation help
     */
    private function renderNavigationHelp(array $items): void
    {
        $this->output->writeLine(str_repeat('─', 60), ConsoleColor::GRAY);
        $this->output->writeLine(implode(' | ', $items), ConsoleColor::BRIGHT_BLUE);
    }

    /**
     * Get history items based on tab
     */
    private function getHistoryItems(HistoryTab $tab, CommandHistory $history): array
    {
        return match ($tab) {
            HistoryTab::RECENT => $history->getRecentHistory(10),
            HistoryTab::FREQUENT => $history->getFrequentCommands(10),
            HistoryTab::FAVORITES => $history->getFavorites(),
        };
    }

    /**
     * Calculate time ago
     */
    private function timeAgo(int $timestamp): string
    {
        $diff = time() - $timestamp;

        if ($diff < 60) {
            return "{$diff}s ago";
        }
        if ($diff < 3600) {
            return floor($diff / 60) . "m ago";
        }
        if ($diff < 86400) {
            return floor($diff / 3600) . "h ago";
        }

        return floor($diff / 86400) . "d ago";
    }
}
