<?php

namespace OtomaticAi\Modules;

use Exception;
use OtomaticAi\Api\OtomaticAi\Client;
use OtomaticAi\Content\CustomHtml;
use OtomaticAi\Content\Video\Youtube;
use OtomaticAi\Models\Contracts\Publishable;
use OtomaticAi\Models\Presets\Preset;
use OtomaticAi\Modules\Contracts\Module as ModuleContract;
use OtomaticAi\Utils\Support;
use OtomaticAi\Vendors\Illuminate\Support\Arr;
use OtomaticAi\Vendors\Illuminate\Support\Str;

class ProcessToolboxModule extends Module implements ModuleContract
{
    const SLUG_NAME = "process_toolbox_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("Toolbox module started.", self::SLUG_NAME);

        // get length
        $length = $this->getLength();

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

        try {
            $toolboxes = [];
            foreach ($placeholders as $placeholder) {
                $toolboxes[] = $this->generateToolbox(Arr::get($placeholder, "type"), Arr::get($placeholder, "data"));
            }

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

                    if ($toolbox) {
                        $el = $toolbox->toHtmlElement($this->html);
                        if ($el) {
                            return $el;
                        }
                    }

                    return "";
                }
            });

            // 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("Toolbox module completed successfully.", self::SLUG_NAME, "success");
        } catch (Exception $e) {
            $this->publication->addLog("Toolbox module failed. " . $e->getMessage(), self::SLUG_NAME, "warning");
        }
    }

    private function generateToolbox(string $type = null, string $data = ""): ?CustomHtml
    {
        try {
            $preset = null;
            switch ($type) {
                case "converter":
                    $preset = Preset::findFromAPI("generate_toolbox_converter");
                    break;
                case "calculator":
                    $preset = Preset::findFromAPI("generate_toolbox_calculator");
                    break;
                case "simulator":
                    $preset = Preset::findFromAPI("generate_toolbox_simulator");
                    break;
                case "infographic":
                    $preset = Preset::findFromAPI("generate_toolbox_infographic");
                    break;
                case "quizz":
                    $preset = Preset::findFromAPI("generate_toolbox_quizz");
                    break;
                case "treemap":
                    $preset = Preset::findFromAPI("generate_toolbox_treemap");
                    break;
                case "timeline":
                    $preset = Preset::findFromAPI("generate_toolbox_timeline");
                    break;
                case "comparison_table":
                    $preset = Preset::findFromAPI("generate_toolbox_comparison_table");
                    break;
                case "charts":
                    $preset = Preset::findFromAPI("generate_toolbox_charts");
                    break;
                default:
                    $preset = Preset::findFromAPI("generate_toolbox");
            }

            if ($preset) {

                // transform preset with the correct model
                $attributes = $preset->toArray();
                Arr::set($attributes, "model", $this->getModuleValue("models.text", "gpt-4o-mini"));
                $preset = Preset::make($attributes);

                $payload = [
                    "title" => $this->publication->title,
                    "language" => $this->getLanguage()->value,
                    "before_fragment" => $data,
                    "after_fragment" => $data,
                    "data" => $data,
                ];

                $response = $preset->process($payload);

                $html = Arr::get($response, 'choices.0.message.content');

                // remove some markdown
                if (!empty($html)) {

                    // convert markdown
                    $html = trim(Support::convertMarkdown($html));

                    // remove emojis if disabled
                    if (!$this->getModuleValue("content.automatic.emojis.enabled", false)) {
                        $html = Support::removeEmojis($html);
                    }

                    // encode emojis for wordpress
                    $html = wp_encode_emoji($html);

                    return new CustomHtml($html);
                }
            }
        } catch (Exception $e) {
            $this->publication->addLog("Toolbox module failed. " . $e->getMessage(), self::SLUG_NAME, "warning");
        }

        return null;
    }

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

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

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

        return true;
    }
}
