<?php

namespace Detektivo\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\ProgressBar;

class Index extends Command {

    protected static $defaultName = 'detektivo:index';
    protected ?\Lime\App $app = null;

    public function __construct(\Lime\App $app) {
        $this->app = $app;
        parent::__construct();
    }

    protected function configure(): void {
        $this
            ->setDescription('Index content in Detektivo search indexes')
            ->setHelp('This command runs the indexer for Detektivo search indexes')
            ->addOption('all', 'a', InputOption::VALUE_NONE, 'Index all configured indexes')
            ->addOption('name', null, InputOption::VALUE_REQUIRED, 'Index a specific index by name')
            ->addOption('rebuild', 'r', InputOption::VALUE_NONE, 'Clear and rebuild the index before indexing');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int {

        $detektivo = $this->app->module('detektivo');
        $indexAll = $input->getOption('all');
        $indexName = $input->getOption('name');
        $rebuild = $input->getOption('rebuild');

        if (!$indexAll && !$indexName) {
            $output->writeln('<error>[x] Please specify --all or --name=<index></error>');
            $output->writeln('');
            $output->writeln('Usage:');
            $output->writeln('  ./tower detektivo:index --all              Index all indexes');
            $output->writeln('  ./tower detektivo:index --name=articles    Index specific index');
            $output->writeln('  ./tower detektivo:index --name=articles --rebuild    Clear and rebuild index');
            return Command::FAILURE;
        }

        $indexes = $detektivo->indexes();

        if (!count($indexes)) {
            $output->writeln('<comment>[!] No indexes configured</comment>');
            return Command::SUCCESS;
        }

        $indexesToProcess = [];

        if ($indexAll) {
            $indexesToProcess = array_keys($indexes);
        } elseif ($indexName) {
            if (!isset($indexes[$indexName])) {
                $output->writeln("<error>[x] Index '{$indexName}' not found</error>");
                $output->writeln('');
                $output->writeln('Available indexes:');
                foreach (array_keys($indexes) as $name) {
                    $output->writeln("  - {$name}");
                }
                return Command::FAILURE;
            }
            $indexesToProcess = [$indexName];
        }

        $output->writeln('');
        $output->writeln('<info>Detektivo Indexer</info>');
        $output->writeln(str_repeat('-', 40));

        $successCount = 0;
        $failCount = 0;

        foreach ($indexesToProcess as $name) {

            $index = $indexes[$name];
            $type = $detektivo->indexTypes($index['type']);

            $output->writeln('');
            $output->writeln("<comment>Processing:</comment> {$name}");
            $output->writeln("  Type: {$index['type']}");

            // Check if indexer is already running
            if ($detektivo->isIndexerRunning($name)) {
                $output->writeln('  <comment>[!] Indexer already running, skipping...</comment>');
                continue;
            }

            // Check if index type has an indexer
            if (!$type || !isset($type['index'])) {
                $output->writeln('  <comment>[!] No indexer configured for this type, skipping...</comment>');
                continue;
            }

            // Rebuild: clear the index first
            if ($rebuild) {
                $output->writeln('  <comment>Clearing index...</comment>');
                $idx = $detektivo->index($name, true);
                if ($idx) {
                    $idx->clear();
                    $output->writeln('  <info>[✓] Index cleared</info>');
                }
            }

            // Run the indexer
            $output->writeln('  <comment>Indexing...</comment>');
            $startTime = microtime(true);

            try {
                $result = $detektivo->runIndexer($name, []);

                if ($result === false) {
                    $output->writeln('  <error>[x] Indexer failed to start</error>');
                    $failCount++;
                } else {
                    $elapsed = round(microtime(true) - $startTime, 2);
                    $output->writeln("  <info>[✓] Indexing completed ({$elapsed}s)</info>");
                    $successCount++;
                }
            } catch (\Throwable $e) {
                $output->writeln("  <error>[x] Error: {$e->getMessage()}</error>");
                $failCount++;
            }
        }

        $output->writeln('');
        $output->writeln(str_repeat('-', 40));
        $output->writeln("<info>Completed:</info> {$successCount} indexed, {$failCount} failed");
        $output->writeln('');

        return $failCount > 0 ? Command::FAILURE : Command::SUCCESS;
    }
}
