<?php

declare(strict_types=1);

namespace App\Command;

use App\Entity\Image;
use App\Entity\ImageRepository;
use App\Entity\ImageImageRepository;
use App\Model\ImageStatus;
use App\Repository\ImageRepository as ImageRepositoryRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;

#[AsCommand(
    name: 'app:create-image-repositories',
    description: 'Crea una ImageRepository y/o ImageImageRepository con datos interactivos'
)]
class CreateImageRepositoriesCommand extends Command
{
    public function __construct(
        private readonly EntityManagerInterface $entityManager,
        private readonly ImageRepositoryRepository $imageRepository
    ) {
        parent::__construct();
    }

    protected function configure(): void
    {
        $this
            ->setDescription('Crea una ImageRepository y/o ImageImageRepository')
            ->addArgument('action', InputArgument::OPTIONAL, 'Acción a realizar: repository, image-repository, o both', 'both')
            ->addOption('repository-name', null, InputOption::VALUE_OPTIONAL, 'Nombre del repositorio de imágenes')
            ->addOption('repository-ip', null, InputOption::VALUE_OPTIONAL, 'IP del repositorio de imágenes')
            ->addOption('repository-user', null, InputOption::VALUE_OPTIONAL, 'Usuario del repositorio', ImageRepository::DEFAULT_USER)
            ->addOption('repository-ssh-port', null, InputOption::VALUE_OPTIONAL, 'Puerto SSH del repositorio')
            ->addOption('repository-comments', null, InputOption::VALUE_OPTIONAL, 'Comentarios del repositorio')
            ->addOption('image-name', null, InputOption::VALUE_OPTIONAL, 'Nombre de la imagen')
            ->addOption('image-type', null, InputOption::VALUE_OPTIONAL, 'Tipo de imagen', 'Server')
            ->addOption('image-version', null, InputOption::VALUE_OPTIONAL, 'Versión de la imagen', '1')
            ->addOption('image-repository-name', null, InputOption::VALUE_OPTIONAL, 'Nombre para ImageImageRepository')
            ->addOption('image-repository-status', null, InputOption::VALUE_OPTIONAL, 'Status para ImageImageRepository', ImageStatus::SUCCESS)
            ->addOption('batch', 'b', InputOption::VALUE_NONE, 'Modo no interactivo (usar solo opciones)');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $action = $input->getArgument('action');
        $batchMode = $input->getOption('batch');

        $helper = $this->getHelper('question');

        $output->writeln('<info>🚀 Creador de ImageRepository e ImageImageRepository</info>');
        $output->writeln('');

        try {
            switch ($action) {
                case 'repository':
                    $imageRepository = $this->createImageRepository($input, $output, $helper, $batchMode);
                    $output->writeln("<success>✅ ImageRepository creado exitosamente: {$imageRepository->getName()}</success>");
                    break;

                case 'image-repository':
                    $imageImageRepository = $this->createImageImageRepository($input, $output, $helper, $batchMode);
                    $output->writeln("<success>✅ ImageImageRepository creado exitosamente: {$imageImageRepository->getName()}</success>");
                    break;

                case 'both':
                default:
                    $output->writeln('<comment>Creando ImageRepository primero...</comment>');
                    $imageRepository = $this->createImageRepository($input, $output, $helper, $batchMode);
                    $output->writeln("<success>✅ ImageRepository creado: {$imageRepository->getName()}</success>");
                    
                    $output->writeln('');
                    $output->writeln('<comment>Ahora creando ImageImageRepository...</comment>');
                    $imageImageRepository = $this->createImageImageRepository($input, $output, $helper, $batchMode, $imageRepository);
                    $output->writeln("<success>✅ ImageImageRepository creado: {$imageImageRepository->getName()}</success>");
                    break;
            }

            $this->entityManager->flush();
            $output->writeln('');
            $output->writeln('<success>🎉 ¡Proceso completado exitosamente!</success>');

            return Command::SUCCESS;

        } catch (\Exception $e) {
            $output->writeln("<error>❌ Error: {$e->getMessage()}</error>");
            return Command::FAILURE;
        }
    }

    private function createImageRepository(InputInterface $input, OutputInterface $output, $helper, bool $batchMode): ImageRepository
    {
        // Recopilar datos para ImageRepository
        $name = $input->getOption('repository-name');
        if (!$name && !$batchMode) {
            $question = new Question('<question>Nombre del repositorio de imágenes: </question>');
            $question->setValidator(function ($value) {
                if (empty($value)) {
                    throw new \RuntimeException('El nombre no puede estar vacío');
                }
                return $value;
            });
            $name = $helper->ask($input, $output, $question);
        }

        $ip = $input->getOption('repository-ip');
        if (!$ip && !$batchMode) {
            $question = new Question('<question>IP del repositorio: </question>');
            $question->setValidator(function ($value) {
                if (empty($value)) {
                    throw new \RuntimeException('La IP no puede estar vacía');
                }
                if (!filter_var($value, FILTER_VALIDATE_IP)) {
                    throw new \RuntimeException('La IP no es válida');
                }
                return $value;
            });
            $ip = $helper->ask($input, $output, $question);
        }

        $user = $input->getOption('repository-user') ?: ImageRepository::DEFAULT_USER;
        if (!$batchMode) {
            $question = new Question("<question>Usuario [{$user}]: </question>", $user);
            $user = $helper->ask($input, $output, $question);
        }

        $sshPort = $input->getOption('repository-ssh-port');
        if (!$sshPort && !$batchMode) {
            $question = new Question('<question>Puerto SSH [22]: </question>', '22');
            $sshPort = $helper->ask($input, $output, $question);
        }

        $comments = $input->getOption('repository-comments');
        if (!$comments && !$batchMode) {
            $question = new Question('<question>Comentarios (opcional): </question>');
            $comments = $helper->ask($input, $output, $question);
        }

        // Crear ImageRepository
        $imageRepository = new ImageRepository();
        $imageRepository->setName($name);
        $imageRepository->setIp($ip);
        $imageRepository->setUser($user);
        $imageRepository->setSshPort($sshPort);
        if ($comments) {
            $imageRepository->setComments($comments);
        }

        $this->entityManager->persist($imageRepository);

        return $imageRepository;
    }

    private function createImageImageRepository(InputInterface $input, OutputInterface $output, $helper, bool $batchMode, ?ImageRepository $repository = null): ImageImageRepository
    {
        // Si no tenemos repository, necesitamos seleccionar uno existente
        if (!$repository) {
            $repositories = $this->imageRepository->findAll();
            if (empty($repositories)) {
                throw new \RuntimeException('No hay ImageRepositories disponibles. Crea uno primero.');
            }

            if (!$batchMode) {
                $output->writeln('<comment>Repositorios disponibles:</comment>');
                foreach ($repositories as $i => $repo) {
                    $output->writeln(" [{$i}] {$repo->getName()} ({$repo->getIp()})");
                }

                $question = new Question('<question>Selecciona un repositorio (número): </question>');
                $question->setValidator(function ($value) use ($repositories) {
                    if (!is_numeric($value) || !isset($repositories[$value])) {
                        throw new \RuntimeException('Selección inválida');
                    }
                    return (int)$value;
                });
                $repoIndex = $helper->ask($input, $output, $question);
                $repository = $repositories[$repoIndex];
            } else {
                $repository = $repositories[0]; // Usar el primero disponible en modo batch
            }
        }

        // Obtener todas las imágenes disponibles
        $images = $this->entityManager->getRepository(Image::class)->findAll();
        $image = null;

        if (!empty($images) && !$batchMode) {
            $output->writeln('<comment>Imágenes disponibles:</comment>');
            foreach ($images as $i => $img) {
                $output->writeln(" [{$i}] {$img->getName()} (Tipo: {$img->getType()})");
            }
            $output->writeln(" [new] Crear nueva imagen");

            $question = new Question('<question>Selecciona una imagen o "new" para crear nueva: </question>');
            $imageChoice = $helper->ask($input, $output, $question);

            if ($imageChoice !== 'new' && is_numeric($imageChoice) && isset($images[$imageChoice])) {
                $image = $images[$imageChoice];
            }
        }

        // Si no hay imagen seleccionada, crear una nueva
        if (!$image) {
            $imageName = $input->getOption('image-name');
            if (!$imageName && !$batchMode) {
                $question = new Question('<question>Nombre de la imagen: </question>');
                $question->setValidator(function ($value) {
                    if (empty($value)) {
                        throw new \RuntimeException('El nombre de la imagen no puede estar vacío');
                    }
                    return $value;
                });
                $imageName = $helper->ask($input, $output, $question);
            }

            $imageType = $input->getOption('image-type') ?: 'Server';
            if (!$batchMode) {
                $question = new Question("<question>Tipo de imagen [{$imageType}]: </question>", $imageType);
                $imageType = $helper->ask($input, $output, $question);
            }

            $imageVersion = $input->getOption('image-version') ?: 1;
            if (!$batchMode) {
                $question = new Question("<question>Versión de la imagen [{$imageVersion}]: </question>", $imageVersion);
                $imageVersion = (int)$helper->ask($input, $output, $question);
            }

            // Crear nueva imagen
            $image = new Image();
            $image->setName($imageName);
            $image->setType($imageType);
            $image->setVersion($imageVersion);
            $image->setRemotePc(false);
            $image->setIsGlobal(true);

            $this->entityManager->persist($image);
        }

        // Recopilar datos para ImageImageRepository
        $imageRepositoryName = $input->getOption('image-repository-name');
        if (!$imageRepositoryName && !$batchMode) {
            $defaultName = $image->getName() . '_' . $repository->getName();
            $question = new Question("<question>Nombre para ImageImageRepository [{$defaultName}]: </question>", $defaultName);
            $imageRepositoryName = $helper->ask($input, $output, $question);
        } elseif (!$imageRepositoryName) {
            $imageRepositoryName = $image->getName() . '_' . $repository->getName();
        }

        $status = $input->getOption('image-repository-status') ?: ImageStatus::SUCCESS;
        if (!$batchMode) {
            $output->writeln('<comment>Status disponibles:</comment>');
            foreach (ImageStatus::getStatusKeys() as $statusKey) {
                $output->writeln(" - {$statusKey}");
            }
            $question = new Question("<question>Status [{$status}]: </question>", $status);
            $question->setValidator(function ($value) {
                if (!in_array($value, ImageStatus::getStatusKeys())) {
                    throw new \RuntimeException('Status inválido');
                }
                return $value;
            });
            $status = $helper->ask($input, $output, $question);
        }

        // Crear ImageImageRepository
        $imageImageRepository = new ImageImageRepository();
        $imageImageRepository->setName($imageRepositoryName);
        $imageImageRepository->setImage($image);
        $imageImageRepository->setRepository($repository);
        $imageImageRepository->setStatus($status);
        $imageImageRepository->setCreated(true);
        $imageImageRepository->setVersion($image->getVersion());

        $this->entityManager->persist($imageImageRepository);

        return $imageImageRepository;
    }
} 