<?php

namespace App\Command;

use App\Entity\Bible;
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\Style\SymfonyStyle;

#[AsCommand(
    name: 'IngestBible',
    aliases: ['app:ingest-bible'],
    description: 'Script used to crawl a directory and ingest Bible passages and save them to the database.',
)]
class IngestBibleCommand extends Command
{
    private array $files = [];

    private SymfonyStyle $io;

    private EntityManagerInterface $emi;

    public function __construct(
        EntityManagerInterface $emi,
        private string $dir = ''
    ) {
        \ini_set('memory_limit', '5G');

        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) {
            $this->io->error('Directory not specific or does not exist');
            return Command::FAILURE;
        }

        $this->io->note("Crawling {$this->dir} and ingesting Bible passages...");

        foreach($this->getFiles() as $file) {
            $this->io->info("Processing ".basename($file));
            $this->processFile($file);
        }

        return Command::SUCCESS;
    }

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

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

        return $this->files;
    }

    private function processFile(string $file)
    {
        $bible = new Bible();

        $match = [];
        if(preg_match("/([\d]+) \- ([^\/]+)\/\d?[a-zA-Z]+([\d]+)\.md/", $file, $match)) {
            $ndx = (int) $match[1];
            $book = str_replace(" ", "", $match[2]);
            $chapter = (int) $match[3];
        }

        if (preg_match("/(\d)([^\d]+)/", $book, $match)) {
            $book = $match[1]." ".$match[2];
        }

        $bible->setBook($book);
        $bible->setBookIndex($ndx);
        $bible->setChapter($chapter);

        $content = file_get_contents($file);
        foreach(explode("\n", $content) as $verse) {
            $match = [];
            if (preg_match("/^([\d]+). ([^\d]+)/", $verse, $match)) {
                $bible->setVerse($match[1]);
                $bible->setContent($match[2]);
            }

            $this->emi->persist($bible);
            $this->emi->flush();
        }
    }
}
