import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import EquationEditor from 'equation-editor-react';
import * as iink from 'iink-js';
import { action, observable, reaction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { WidthSym } from '../../../fields/Doc';
import { Id } from '../../../fields/FieldSymbols';
import { NumCast, StrCast } from '../../../fields/Types';
import { TraceMobx } from '../../../fields/util';
import { Docs } from '../../documents/Documents';
import { ViewBoxBaseComponent } from '../DocComponent';
import { LightboxView } from '../LightboxView';
import './EquationBox.scss';
import { FieldView, FieldViewProps } from './FieldView';

@observer
export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(EquationBox, fieldKey); }
    public static SelectOnLoad: string = "";

    _ref: React.RefObject<EquationEditor> = React.createRef();
    @observable _inkOpen = false;
    @observable _inkEditor: any;
    @observable _inkRef: any;

    componentDidMount() {
        if (EquationBox.SelectOnLoad === this.rootDoc[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.props.docViewPath()))) {
            this.props.select(false);

            this._ref.current!.mathField.focus();
            this._ref.current!.mathField.select();
        }
        reaction(() => StrCast(this.dataDoc.text),
            text => {
                if (text && text !== this._ref.current!.mathField.latex()) {
                    this._ref.current!.mathField.latex(text);
                }
            });
        reaction(() => this.props.isSelected(),
            selected => {
                if (this._ref.current) {
                    if (selected) this._ref.current.element.current.children[0].addEventListener("keydown", this.keyPressed, true);
                    else this._ref.current.element.current.children[0].removeEventListener("keydown", this.keyPressed);
                }
            }, { fireImmediately: true });
    }

    componentWillUnmount() {
        this._inkRef.removeEventListener('exported', this.exportInk);
    }

    @action
    keyPressed = (e: KeyboardEvent) => {
        const _height = Number(getComputedStyle(this._ref.current!.element.current).height.replace("px", ""));
        const _width = Number(getComputedStyle(this._ref.current!.element.current).width.replace("px", ""));
        if (e.key === "Enter") {
            const nextEq = Docs.Create.EquationDocument({
                title: "# math", text: StrCast(this.dataDoc.text), _width, _height: 25,
                x: NumCast(this.layoutDoc.x), y: NumCast(this.layoutDoc.y) + _height + 10
            });
            EquationBox.SelectOnLoad = nextEq[Id];
            this.props.addDocument?.(nextEq);
            e.stopPropagation();

        }
        if (e.key === "Tab") {
            const graph = Docs.Create.FunctionPlotDocument([this.rootDoc], {
                x: NumCast(this.layoutDoc.x) + this.layoutDoc[WidthSym](),
                y: NumCast(this.layoutDoc.y),
                _width: 400, _height: 300, backgroundColor: "white"
            });
            this.props.addDocument?.(graph);
            e.stopPropagation();
        }
        if (e.key === "Backspace" && !this.dataDoc.text) this.props.removeDocument?.(this.rootDoc);
    }

    onChange = (str: string) => {
        this.dataDoc.text = str;
        const style = this._ref.current && getComputedStyle(this._ref.current.element.current);
        if (style) {
            const _height = Number(style.height.replace("px", ""));
            const _width = Number(style.width.replace("px", ""));
            this.layoutDoc._width = Math.max(35, _width);
            this.layoutDoc._height = Math.max(25, _height);
        }
    }

    @action
    toggleInk = (e: React.PointerEvent) => {
        e.stopPropagation();

        this._inkOpen = !this._inkOpen;

        if (!this._inkEditor) {
            this._inkEditor = this._inkRef ? iink.register(this._inkRef, {
                recognitionParams: {
                    type: 'MATH',
                    protocol: 'WEBSOCKET',
                    server: {
                        host: 'cloud.myscript.com',
                        applicationKey: '7277ec34-0c2e-4ee1-9757-ccb657e3f89f',
                        hmacKey: 'f5cb18f2-1f95-4ddb-96ac-3f7c888dffc1',
                    },
                    iink: {
                        math: {
                            mimeTypes: ['application/x-latex', 'application/vnd.myscript.jiix']
                        },
                        export: {
                            jiix: {
                                strokes: true
                            }
                        }
                    }
                }
            }) : null;

            this._inkRef.addEventListener('exported', this.exportInk)
        }
    }

    convertInk = (e: React.MouseEvent) => {
        this._inkRef.editor.convert();
    }

    clearInk = (e: React.MouseEvent) => {
        this._inkRef.editor.clear();
        this.onChange("");
    }

    exportInk = (e: any) => {
        const exports = e.detail.exports;
        if (exports && exports['application/x-latex']) {
            this.onChange(exports['application/x-latex']);
            console.log(JSON.parse(exports['application/vnd.myscript.jiix']).expressions[0].items[0]);
        }
    }


    render() {
        TraceMobx();
        const scale = (this.props.scaling?.() || 1) * NumCast(this.layoutDoc._viewScale, 1);
        return (<div className="equationBox-cont"
            onPointerDown={e => !e.ctrlKey && e.stopPropagation()}
            style={{
                transform: `scale(${scale})`,
                width: `calc(${100 / scale}% + 25px)`,
                height: `${100 / scale}%`,
                pointerEvents: !this.props.isSelected() ? "none" : undefined,
            }}
            onKeyDown={e => e.stopPropagation()}>

            <EquationEditor ref={this._ref}
                value={this.dataDoc.text || "x"}
                spaceBehavesLikeTab={true}
                onChange={this.onChange}
                autoCommands="pi theta sqrt sum prod alpha beta gamma rho"
                autoOperatorNames="sin cos tan" />

            <div className="button"
                style={{ display: this.props.isContentActive() ? "flex" : "none" }}
                onPointerDown={this.toggleInk}>
                <FontAwesomeIcon icon="pencil-alt" />
            </div>

            <div className='ink-editor'
                ref={action((r: any) => this._inkRef = r)}
                id="editor" onPointerDown={(e) => e.stopPropagation()}
                touch-action="none"
                style={{ display: this._inkOpen && this.props.isContentActive() ? "block" : "none" }}>
                <button onClick={this.convertInk}>convert</button>
                <button onClick={this.clearInk}>clear</button>
            </div>

        </div>);
    }
}