<?php

namespace App\Command;

use App\Entity\Reference;

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\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
    name: 'app:import-heidelberg',
    description: 'Import Heidelberg Catechism',
)]
class ImportHeidelbergCommand extends Command
{

    /**
     * IO
     *
     * @var SymfonyStyle
     */
    private SymfonyStyle $io;

    /**
     * EntityManager
     *
     * @var EntityManagerInterface
     */
    private EntityManagerInterface $emi;

    /**
     * @param EntityManagerInterface $emi
     */
    public function __construct(
        EntityManagerInterface $emi,
        private string $dir = ''
    ) {
        parent::__construct();
        $this->emi = $emi;
    }

    protected function configure(): void
    {
        $this
            ->addArgument('directory', InputArgument::REQUIRED, 'Directory to crawl')
        ;
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $this->io = new SymfonyStyle($input, $output);
        $this->dir = $input->getArgument('directory');

        if (!$this->dir || !file_exists($this->dir)) {
            $this->io->error('Directory not specified or does not exist');
            return Command::FAILURE;
        }

        $this->io->note("Crawling {$this->dir} for Heidelberg Catechism Q&A's");
        $files = $this->getFiles();
        
        $this->io->progressStart(count($files));
        foreach ($files as $file) {
            $basename = basename($file);
            //$io->info("Processing ".basename($file));
            $this->processFile($file);
            $this->io->progressAdvance();
        }
        $this->io->progressFinish();

        return Command::SUCCESS;
    }

    private function getFiles(): array
    {
        $files = glob($this->dir . "/*.md");

        if (!$files || count($files) === 0) {
            $this->io->warning("No files found in this directory\n{$this->dir}");
            $files = [];
        }
        natsort($files);
        return $files;
    }

    private function processFile(string $file): Reference|bool
    {
        $md = trim(file_get_contents($file));
        $ref = new Reference();

        if (!$md) {
            $this->io->warning("File is empty\n{$file}");
            return false;
        }

        $match = [];
        if (preg_match("/LD(\d+)\-HC(\d+)/", $file, $match)) {
            $type = 'hc';
            $label = "LD{$match[1]}-HC{$match[2]}";
            $name = 'Heidelberg';
        }

        $ref->setNdx($match[2]);
        $ref->setLabel($label);
        $ref->setType($type);
        $ref->setName($name);
        $ref->setContent($md);

        $this->emi->persist($ref);
        $this->emi->flush();

        return $ref;
    }
}
