<?php

namespace onespace\tools\widgets\TinyMCE;

use onespace\tools\assets\TinyMCEAsset;
use Yii;
use yii\helpers\Html;
use yii\web\View;
use yii\widgets\InputWidget;

/**
 * @author  Gareth Palmer <gareth@one-space.co.za>
 * 
 * @see https://www.tiny.cloud/docs/
 * @see https://www.tiny.cloud/docs/plugins/opensource/imagetools/
 */

final class TinyMCE extends InputWidget {

    /**
     * @see https://www.tiny.cloud/docs/tinymce/6/available-menu-items/
     */
    public string $menubar = 'file edit view insert format table';

    /**
     * @see https://www.tiny.cloud/docs/tinymce/6/available-toolbar-buttons/
     */
    public string $toolbar = 'undo redo | blocks | bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | fontfamily | bullist numlist outdent indent | link unlink image | wordcount charmap emoticons removeformat hr';

    /**
     * @see https://www.tiny.cloud/docs/tinymce/6/plugins/
     */
    public string $plugins = 'advlist autolink lists link image charmap preview anchor pagebreak table media wordcount charmap emoticons';

    /**
     * @see https://www.tiny.cloud/docs/tinymce/6/user-formatting-options/#font_family_formats
     */
    public array $fonts = [
        "Andale Mono=andale mono, monospace",
        "Arial=arial, helvetica, sans-serif",
        "Arial Black=arial black, sans-serif",
        "Book Antiqua=book antiqua, palatino, serif",
        "Comic Sans MS=comic sans ms, sans-serif",
        "Courier New=courier new, courier, monospace",
        "Georgia=georgia, palatino, serif",
        "Helvetica=helvetica, arial, sans-serif",
        "Impact=impact, sans-serif",
        "Open Sans=Open Sans",
        "Symbol=symbol",
        "Tahoma=tahoma, arial, helvetica, sans-serif",
        "Terminal=terminal, monaco, monospace",
        "Times New Roman=times new roman, times, serif",
        "Trebuchet MS=trebuchet ms, geneva, sans-serif",
        "Verdana=verdana, geneva, sans-serif",
        "Webdings=webdings",
        "Wingdings=wingdings, zapf dingbats",
    ];

    /**
     * @see https://www.tiny.cloud/docs/tinymce/6/add-css-options/#font_css
     */
    public ?string $fontCss = null;

    /**
     * Allow or disallow the use of uploading images (which are automatically converted to base64)
     *
     * @var boolean Default: true
     */
    public bool $uploadImages = true;


    /**
     * {@inheritdoc}
     */

    public function init() {
        TinyMCEAsset::register($this->getView());

        if (isset($this->model) && isset($this->attribute)) {
            $this->name = Html::getInputName($this->model, $this->attribute);
            parent::init();
            $this->id = 'mce' . str_replace('-', '_', Yii::$app->security->generateRandomString(8));
            $this->options['id'] = $this->id;
            $this->options['name'] = $this->name;
        }

        $view = $this->getView();
        $view->registerCss(<<<CSS
            .tox-promotion,
            .tox-statusbar__branding {
                display: none;
            }
        CSS, ['position' => View::POS_HEAD]);

        $fontImport = '';
        if (!empty($this->fontCss)) {
            $fontImport = "font_css: '{$this->fontCss}',";
        }

        $fonts = implode(';', $this->fonts);

        $uploadImages = '';
        if ($this->uploadImages) {
            $uploadImages = <<<JS
            image_title: true,
            automatic_uploads: true,
            file_picker_types: 'image',
            file_picker_callback: (cb, value, meta) => {
                const input = document.createElement('input');
                input.setAttribute('type', 'file');
                input.setAttribute('accept', 'image/*');

                input.addEventListener('change', (e) => {
                    const file = e.target.files[0];

                    const reader = new FileReader();
                    reader.addEventListener('load', () => {
                        const id = 'blobid' + (new Date()).getTime();
                        const blobCache =  tinymce.activeEditor.editorUpload.blobCache;
                        const base64 = reader.result.split(',')[1];
                        const blobInfo = blobCache.create(id, file, base64);
                        blobCache.add(blobInfo);
                        cb(blobInfo.blobUri(), { title: file.name });
                    });
                    reader.readAsDataURL(file);
                });

                input.click();
            },
            JS;
        }

        /**
         * @see https://www.tiny.cloud/docs/tinymce/6/file-image-upload/#interactive-example
         */
        $view->registerJs(<<<JS
            tinymce.init({
                selector: '#{$this->id}',
                promotion: false,
                menubar: '{$this->menubar}',
                toolbar: '{$this->toolbar}',
                plugins: '{$this->plugins}',
                {$fontImport}
                font_family_formats: '$fonts',
                {$uploadImages}
            });
        JS);
    }


    /**
     * {@inheritdoc}
     * 
     * @return  string
     */

    public function run(): string {
        parent::run();
        if ($this->hasModel()) {
            return Html::activeTextarea($this->model, $this->attribute, $this->options);
        }
        $this->options['id'] = $this->id;
        return Html::textarea($this->name, $this->value, $this->options);
    }
}
