<?php

namespace Bongo\Builder\Seeders;

use Bongo\Builder\Models\BuilderItem;
use DOMDocument;
use Exception;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;

class ComponentSeeder extends Seeder
{
    /**
     * @throws Exception
     */
    public function run(): void
    {
        // This is only run if we have to re-import the content.js plugin file
        if (file_exists(__DIR__.'/components.js')) {
            $fileData = $this->cleanContentsFile();
            File::put(__DIR__.'/components.json', $fileData);
        }

        // Make sure we have the components.json file
        if (! file_exists(__DIR__.'/components.json')) {
            throw new Exception('File components.json does not exist to import');
        }

        // Get the json components from the components file
        $jsonComponents = File::get(__DIR__.'/components.json');
        $jsonComponents = json_decode($jsonComponents, true);
        $defaultImage = File::get(public_path('images/default_image.png'));

        // Loop through and create the files
        foreach ($jsonComponents as $jsonComponent) {
            try {
                // Get the component name from the image preview
                $name = str_replace('preview/', '', $jsonComponent['thumbnail']);
                $name = str_replace('.png', '', $name);

                // Create the directories
                $categories = config('builder.categories');
                foreach ($categories as $category) {
                    $directory = base_path(config('builder.vendor_path').config('builder.component_path')).trim(strtolower(Str::slug($category)));
                    if (! File::exists($directory)) {
                        File::makeDirectory($directory);
                    }
                }

                // Create the component
                $component = new BuilderItem('component');
                $component->setName($name);
                $component->setKey($name);

                // Get the thumbnail
                if (file_exists(__DIR__.'/component/'.$jsonComponent['thumbnail'])) {
                    $component->setThumbnail(File::get(__DIR__.'/component/'.$jsonComponent['thumbnail']));
                } else {
                    $component->setThumbnail($defaultImage);
                }

                // Set the category
                $categories = config('builder.categories');
                $component->setCategory($categories[$jsonComponent['category']]);

                // Turn off DOMDocument HTML warnings
                libxml_use_internal_errors(true);

                // Fix any missing tags
                $dom = new DOMDocument();
                $dom->preserveWhiteSpace = false;
                $dom->loadHTML($jsonComponent['html']);
                $dom->formatOutput = true;
                $html = $dom->saveXML($dom, LIBXML_NOEMPTYTAG);

                // Strip the elements we dont need
                $html = str_replace('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'."\n", '', $html);
                $html = str_replace('<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">'."\n",
                    '', $html);
                $html = str_replace('<html>', '', $html);
                $html = str_replace('</html>', '', $html);
                $html = str_replace('<body>', '', $html);
                $html = str_replace('</body>', '', $html);

                // Remove the whitespace at the start and end
                $html = trim($html);

                // Save
                $component->setHtml($html);
                $component->save();

            } catch (Exception $e) {
                console_print($e);
                continue;
            }
        }
    }

    private function cleanContentsFile(): array|string
    {
        // Get an array of the phone prefixes
        $fileData = File::get(__DIR__.'/components.js', true);

        // Replace all return and new line characters
        $fileData = preg_replace("/\r|\n/", '', $fileData);
        $fileData = str_replace('\n', '', $fileData);

        // Remove the js concatenations
        $fileData = str_replace('+', '', $fileData);

        // Replace any javascript tab functions
        $fileData = str_replace('_tabs(1)', '', $fileData);
        $fileData = str_replace('_tabs(2)', '', $fileData);
        $fileData = str_replace('_tabs(3)', '', $fileData);
        $fileData = str_replace('_tabs(4)', '', $fileData);
        $fileData = str_replace('_tabs(5)', '', $fileData);
        $fileData = str_replace('_tabs(6)', '', $fileData);
        $fileData = str_replace('_tabs(7)', '', $fileData);
        $fileData = str_replace('_tabs(8)', '', $fileData);
        $fileData = str_replace('_tabs(9)', '', $fileData);
        $fileData = str_replace('_tabs(10)', '', $fileData);

        // Replace multiple spaces with a single space
        $fileData = preg_replace('/\s+/', ' ', $fileData);
        $fileData = preg_replace('/>\s+</m', '><', $fileData);

        // Escape all the html double quotes
        $fileData = preg_replace_callback('/<([^<>]+)>/', function ($matches) {
            return str_replace('"', '\"', $matches[0]);
        }, $fileData);

        // Escape all the double quotes in the content
        $fileData = preg_replace_callback('/>(.*?)</', function ($matches) {
            return str_replace('"', '', $matches[0]);
        }, $fileData);

        // Make sure the first and last character in the html block have a double quote
        $fileData = str_replace("'html' : '", "'html' : ".'"', $fileData);
        $fileData = str_replace("' }", '" }', $fileData);

        // Strip all incorrect literals
        $fileData = str_replace("'<", '<', $fileData);
        $fileData = str_replace(">'", '>', $fileData);

        // Replace all single quotes with double quotes
        $fileData = str_replace("'", '"', $fileData);
        $fileData = str_replace('// {', '', $fileData);

        // Remove placeholder text
        $fileData = str_replace('"PRODUCT NAME"', '', $fileData);

        // Update the image paths
        $fileData = str_replace('assets/minimalist-blocks/', '/snippets/images/', $fileData);
        $fileData = str_replace('[%IMAGE_PATH%]', '/snippets/images/', $fileData);

        return $fileData;
    }
}
