<?php

declare(strict_types=1);

namespace app\vendor\apexl\io\src\Io\modules\system\commands;

use apexl\Io\exceptions\RecordNotFoundException;
use apexl\Io\modules\system\services\ModuleClassResolver;
use apexl\Vault\Vault;
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\Style\SymfonyStyle;

#[AsCommand(name: 'modules:deactivate ', description: 'Deactivate a module')]
class ModuleDeactivateCommand extends DaedalusCommand
{
    private SymfonyStyle $io;
    private InputInterface $input;

    public function __construct(
        private readonly Vault $db,
        private readonly ModuleClassResolver $classResolver,
        ?string $name = null
    ) {
        parent::__construct($name);
    }

    protected function configure(): void
    {
        $this->addArgument('module', InputArgument::REQUIRED, 'The module to activate');
        $this->addOption('delete', 'd', InputOption::VALUE_NONE, 'Remove entry from modules table');
    }

    private function deactivateModule(string $moduleClass): void
    {
        $result = $this->db->select('modules')
            ->fields('installed')
            ->where('module', $moduleClass)
            ->execute()
            ->fetch();

        if (!$result) {
            $this->io->warning(sprintf('Module `%s` is not installed', $moduleClass));
            return;
        }

        if ($result->installed === 0 && !$this->input->getOption('delete')) {
            $this->io->warning(sprintf('Module `%s` already deactivated', $moduleClass));
            return;
        }

        if ($this->input->getOption('delete')) {
            $this->deleteModule($moduleClass);
            return;
        }

        $this->updateModule($moduleClass);
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->io = new SymfonyStyle($input, $output);
        $this->input = $input;
        $module = $input->getArgument('module');
        try {
            $moduleClass = $this->classResolver->resolve($module);

            $this->deactivateModule($moduleClass);

            $this->io->success(
                sprintf('%s %s', $this->input->getOption('delete') ? 'Deleted' : 'Deactivated', $moduleClass)
            );

            return Command::SUCCESS;
        } catch (RecordNotFoundException $e) {
            $this->io->error(sprintf('Could not resolve module `%s`: %s', $module, $e->getMessage()));

            return Command::FAILURE;
        }
    }

    private function deleteModule(string $moduleClass): void
    {
        $this->db->delete('modules')
            ->where('module', $moduleClass)
            ->execute();
    }

    private function updateModule(string $moduleClass)
    {
        $this->db->update('modules')
            ->fields([
                'installed' => 0,
                'lastUninstallDate' => time(),
            ])
            ->where('module', $moduleClass)
            ->execute();

    }
}
