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

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

    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 || !file_exists($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...");

        $this->json = json_decode(file_get_contents("{$this->dir}/esv-bible.json"));
        foreach ($this->json as $book => $data) {
            $index = $data->index;
            $chapters = $data->chapters;
            $label = $data->label;
            foreach ($data->text as $chapter => $verses) {
                foreach ($verses as $idx => $verseText) {
                    print "$book $chapter:".($idx + 1).PHP_EOL;
                    $bible = $this->processFile($this->json,  $book, $chapter, $idx);

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

        return Command::SUCCESS;
    }

    private function processFile(object &$json, string $book, int $chapter, int $verse): Bible
    {
        $bible = new Bible();

        $bible->setChapter((int) $chapter);
        $bible->setVerse((int) ($verse + 1));
        $bible->setLabel($json->{$book}->label);
        $bible->setBookIndex((int) $json->{$book}->index);
        $bible->setContent($json->{$book}->text->$chapter[$verse]);
        if (preg_match("/(\d)([^\d]+)/", $book, $match)) {
            $book = $match[1]." ".$match[2];
        }

        $bible->setBook($book);

        return $bible;
    }
}
