<?php

declare(strict_types=1);

namespace OCA\Mitgliederverwaltung\Command;

use OCA\Mitgliederverwaltung\Service\SelfUpdateService;
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\Question\ConfirmationQuestion;

class AppUpdateCommand extends Command {

    private SelfUpdateService $updateService;

    public function __construct(SelfUpdateService $updateService) {
        parent::__construct();
        $this->updateService = $updateService;
    }

    protected function configure(): void {
        $this->setName('mitgliederverwaltung:app:update')
            ->setDescription('Check for and install updates from Gitea releases')
            ->addOption('check', 'c', InputOption::VALUE_NONE, 'Only check for updates, do not install')
            ->addOption('force', 'f', InputOption::VALUE_NONE, 'Install even if version is not newer')
            ->addOption('yes', 'y', InputOption::VALUE_NONE, 'Skip confirmation prompt');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int {
        $checkOnly = $input->getOption('check');

        $output->writeln('Checking for updates...');
        $info = $this->updateService->checkForUpdate();

        $output->writeln('  Current version: v' . $info['currentVersion']);

        if (isset($info['error'])) {
            $output->writeln('<error>Update-Check fehlgeschlagen: ' . $info['error'] . '</error>');
            return Command::FAILURE;
        }

        if ($info['latestVersion'] === null) {
            $output->writeln('  No releases found on Gitea.');
            return Command::SUCCESS;
        }

        $output->writeln('  Latest release:  v' . $info['latestVersion']);
        $output->writeln('  Signed:          ' . (($info['signed'] ?? false) ? '<info>Yes</info>' : '<comment>No</comment>'));

        if (!$info['available']) {
            $output->writeln('<info>Already up to date.</info>');
            if (!$checkOnly && !$input->getOption('force')) {
                return Command::SUCCESS;
            }
        } else {
            $output->writeln('<comment>Update available!</comment>');
            if ($info['releaseName']) {
                $output->writeln('  Release: ' . $info['releaseName']);
            }
        }

        if ($checkOnly) {
            return Command::SUCCESS;
        }

        // Confirmation
        if (!$input->getOption('yes')) {
            $output->writeln('');
            $output->writeln('<comment>This will replace the app files with the new version.</comment>');
            $output->writeln('<comment>Run "occ upgrade" afterwards to apply database migrations.</comment>');
            $helper = $this->getHelper('question');
            $question = new ConfirmationQuestion('Install update? [y/N] ', false);
            if (!$helper->ask($input, $output, $question)) {
                $output->writeln('Update cancelled.');
                return Command::SUCCESS;
            }
        }

        $output->writeln('');
        $output->writeln('Downloading and installing...');

        $result = $this->updateService->performUpdate($input->getOption('force'));

        if ($result['success']) {
            $output->writeln('<info>' . $result['message'] . '</info>');
            $output->writeln('');
            $output->writeln('Next step: run <comment>occ upgrade</comment> to apply database migrations.');
            return Command::SUCCESS;
        } else {
            $output->writeln('<error>' . $result['message'] . '</error>');
            return Command::FAILURE;
        }
    }
}
