<?php

namespace OtomaticAi\Modules;

use DOMDocument;
use Exception;
use OtomaticAi\Content\Faq\Faq;
use OtomaticAi\Models\Contracts\Publishable;
use OtomaticAi\Modules\Contracts\Module as ModuleContract;
use OtomaticAi\Vendors\Illuminate\Support\Arr;

class ProcessFaqModule extends Module implements ModuleContract
{
    const SLUG_NAME = "process_faq_module";

    /**
     * Execute the job.
     *
     * @return void
     * @throws Exception
     */
    public function handle(): void
    {
        // verify that the job is runnable
        if (!$this->isRunnable()) {
            return;
        }

        // log the start of the job
        $this->publication->addLog("FAQ module started.", self::SLUG_NAME);

        // create youtube placeholders
        $placeholders = $this->createElementPlaceholders("faq");

        try {

            // replace faq placeholders with the generated faqs
            $this->replaceElementPlaceholders("faq", function ($attributes) use ($placeholders) {
                $index = Arr::get($attributes, "index");
                if ($index !== null && array_key_exists($index, $placeholders)) {

                    $hn = "h3";

                    $htmlContent = Arr::get($placeholders[$index], "html_content", "");

                    if (empty($htmlContent)) {
                        return "";
                    }

                    $doc = new DOMDocument('1.0', 'UTF-8');
                    libxml_use_internal_errors(true);
                    $doc->loadHTML('<?xml encoding="UTF-8">' . $htmlContent, LIBXML_NOWARNING);
                    libxml_use_internal_errors(false);

                    $questionsNodes = $doc->getElementsByTagName("otofaqquestion");
                    if ($questionsNodes->length === 0) {
                        return "";
                    }

                    $questions = [];
                    foreach ($questionsNodes as $questionNode) {
                        $questions[] = [
                            "title" => $questionNode->getAttribute("title"),
                            "description" => $questionNode->getAttribute("description"),
                        ];
                    }

                    if (empty($questions)) {
                        return "";
                    }

                    return (new Faq($hn, $questions))->toHtmlElement($this->html);
                }
            });

            // add the html content to the generation state
            $this->generationState->setArtifact("html_content", trim(preg_replace("/^<body>|<\/body>$/", "", $this->html->saveHTML($this->html->getElementsByTagName("body")->item(0)))));

            // log the end of the job
            $this->publication->addLog("FAQ module completed successfully.", self::SLUG_NAME, "success");
        } catch (Exception $e) {
            $this->publication->addLog("FAQ module failed. " . $e->getMessage(), self::SLUG_NAME, "warning");
        }
    }

    /**
     * Get the number of FAQ elements
     *
     * @return integer
     */
    private function getLength(): int
    {
        return $this->countElements("faq");;
    }

    /**
     * Determine if the module is runnable
     *
     * @return boolean
     */
    public function isRunnable(): bool
    {
        // must have faq elements
        return $this->getLength() > 0;
    }

    static public function isEnabled(Publishable $publishable): bool
    {
        if (!self::getPublicationModuleValue($publishable, "content.automatic.faq.enabled", false)) {
            return false;
        }

        return true;
    }
}
