import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Tooltip } from '@material-ui/core';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import React from 'react';
import { ColorState, SketchPicker } from 'react-color';
import { Doc, StrListCast } from '../../../../fields/Doc';
import { createSchema, makeInterface } from '../../../../fields/Schema';
import { ScriptField } from '../../../../fields/ScriptField';
import { BoolCast, Cast, StrCast } from '../../../../fields/Types';
import { SelectionManager } from '../../../util/SelectionManager';
import { ColorScheme } from '../../../util/SettingsManager';
import { undoBatch, UndoManager } from '../../../util/UndoManager';
import { ContextMenu } from '../../ContextMenu';
import { DocComponent } from '../../DocComponent';
import { StyleProp } from '../../StyleProvider';
import { FieldView, FieldViewProps } from '../FieldView';
import { FontIconBadge } from './FontIconBadge';
import './FontIconBox.scss';
const FontIconSchema = createSchema({
    icon: "string",
});

export enum ButtonType {
    MenuButton = "menuBtn",
    DropdownList = "drpdownList",
    DropdownButton = "drpdownBtn",
    ClickButton = "clickBtn",
    DoubleButton = "dblBtn",
    ToggleButton = "tglBtn",
    ColorButton = "colorBtn"
}

type FontIconDocument = makeInterface<[typeof FontIconSchema]>;
const FontIconDocument = makeInterface(FontIconSchema);
@observer
export class FontIconBox extends DocComponent<FieldViewProps, FontIconDocument>(FontIconDocument) {
    public static LayoutString(fieldKey: string) { return FieldView.LayoutString(FontIconBox, fieldKey); }
    showTemplate = (): void => {
        const dragFactory = Cast(this.layoutDoc.dragFactory, Doc, null);
        dragFactory && this.props.addDocTab(dragFactory, "add:right");
    }
    dragAsTemplate = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('getCopy(this.dragFactory, true)'); };
    useAsPrototype = (): void => { this.layoutDoc.onDragStart = ScriptField.MakeFunction('makeDelegate(this.dragFactory, true)'); };

    specificContextMenu = (): void => {
        if (!Doc.UserDoc().noviceMode) {
            const cm = ContextMenu.Instance;
            cm.addItem({ description: "Show Template", event: this.showTemplate, icon: "tag" });
            cm.addItem({ description: "Use as Render Template", event: this.dragAsTemplate, icon: "tag" });
            cm.addItem({ description: "Use as Prototype", event: this.useAsPrototype, icon: "tag" });
        }
    }



    // Determining UI Specs
    @observable private label = StrCast(this.rootDoc.label, StrCast(this.rootDoc.title));
    @observable private color = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.Color);
    @observable private backgroundColor = this.props.styleProvider?.(this.rootDoc, this.props, StyleProp.BackgroundColor);
    @observable private icon = StrCast(this.dataDoc.icon, "user") as any;
    @observable private dropdown: boolean = BoolCast(this.rootDoc.dropDownOpen);
    @observable private dropdownDirection: string = StrCast(this.rootDoc.dropDownDirection);
    @observable private buttonList: string[] = StrListCast(this.rootDoc.btnList);
    @observable private activeFont: string = StrCast(Doc.UserDoc()._fontFamily);
    @observable private type = StrCast(this.rootDoc.btnType);

    /**
     * Types of buttons in dash:
     * - Main menu button (LHS)
     * - Tool button
     * - Expandable button (CollectionLinearView)
     * - Button inside of CollectionLinearView vs. outside of CollectionLinearView
     * - Action button
     * - Dropdown button 
     * - Color button
     * - Dropdown list
    **/

    /**
     * Dropdown button
     */
    @computed get dropdownButton() {
        const active: string = StrCast(this.rootDoc.dropDownOpen);
        return (
            <div className={`menuButton ${this.type} ${active}`}
                style={{ color: "black", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
                onClick={action(() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen)}>
                <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={this.color} />
                {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: this.color, backgroundColor: this.backgroundColor }}> {this.label} </div>}
                <div
                    className="menuButton-dropdown"
                    style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
                    <FontAwesomeIcon icon={'caret-down'} color={"black"} size="sm" />
                </div>
                {this.rootDoc.dropDownOpen ?
                    <div className="menuButton-dropdownBox"
                        style={{ left: 0 }}>
                        {/* DROPDOWN BOX CONTENTS */}
                    </div> : null}
            </div>
        );
    }

    @undoBatch setColor = action((color: ColorState, docColor?: string, userColor?: string) => {
        console.log(docColor, userColor);
        if (docColor) {
            const numSelected = SelectionManager.Views().length;
            const selectedDoc = numSelected > 0 ? SelectionManager.Views()[0].Document : undefined;
            eval(docColor);
        }
        else if (userColor) {
            const userDoc = Doc.UserDoc();
            eval(userColor);
        }
    });



    /**
     * Default
     */
    @computed get defaultButton() {
        const active: string = StrCast(this.rootDoc.dropDownOpen);
        return (
            <div className={`menuButton ${this.type}`} onContextMenu={this.specificContextMenu}
                style={{ backgroundColor: "transparent", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}>
                <div className="menuButton-wrap">
                    <FontAwesomeIcon className={`menuButton-icon-${this.type}`} icon={this.icon} color={"black"} size={"sm"} />
                    {!this.label || !Doc.UserDoc()._showLabel ? (null) : <div className="fontIconBox-label" style={{ color: this.color, backgroundColor: this.backgroundColor }}> {this.label} </div>}
                    <FontIconBadge collection={Cast(this.rootDoc.watchedDocuments, Doc, null)} />
                </div>
            </div>
        )
    }


    render() {
        // Variables called through eval (from button)
        const canUndo: boolean = UndoManager.CanUndo();
        const canRedo: boolean = UndoManager.CanRedo();
        const numSelected = SelectionManager.Views().length;
        const selectedDoc = numSelected > 0 ? SelectionManager.Views()[0].Document : undefined;
        const userDoc = Doc.UserDoc();

        // Toggle and canClick properties as determined from the variable passed into the button doc
        // const toggle = this.rootDoc.toggle ? ScriptCast(this.rootDoc.toggle) : undefined;
        const canClick: boolean = this.rootDoc.canClick ? eval(StrCast(this.rootDoc.canClick)) : false;
        // if (toggle) {
        //     console.log(StrCast(this.rootDoc.title), toggle);
        //     toggle.script.run();
        // }
        const dark: boolean = Doc.UserDoc().colorScheme === ColorScheme.Dark;

        const active: string = StrCast(this.rootDoc.dropDownOpen);
        const label = !this.label || !Doc.UserDoc()._showLabel ? (null) :
            <div className="fontIconBox-label" style={{ color: this.color, backgroundColor: this.backgroundColor }}>
                {this.label}
            </div>;
        const menuLabel = !this.label || !Doc.UserDoc()._showMenuLabel ? (null) :
            <div className="fontIconBox-label" style={{ color: this.color, backgroundColor: this.backgroundColor }}>
                {this.label}
            </div>;
        const dropdownCaret = <div
            className="menuButton-dropDown"
            style={{ borderBottomRightRadius: this.dropdown ? 0 : undefined }}>
            <FontAwesomeIcon icon={'caret-down'} color={"black"} size="sm" />
        </div>;
        const colorBox = (func: (color: ColorState) => void) => <SketchPicker onChange={func} color={StrCast(this.backgroundColor)}
            presetColors={['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505',
                '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B',
                '#FFFFFF', '#f1efeb', 'transparent']} />;
        const items = this.buttonList.map((value) => {
            return <div className="list-item"
                style={{ fontFamily: value }}
                onClick={() => Doc.UserDoc()._fontFamily = value}>
                {value}
            </div>;
        });

        /**
         * Menu Panel Button: menuBtn
         * Dropdown Button: dropDownBtn
         * doubleBtn
        **/

        // CODEDUMP: glr
        // const presSize = type === ButtonType.MenuButton ? 30 : 25;
        // const presTrailsIcon = <img src={`/assets/${"presTrails.png"}`}
        //     style={{ width: presSize, height: presSize, filter: `invert(${this.color === "white" ? "100%" : "0%"})`, marginBottom: "5px" }} />;

        // TODO:glr Add label of button type
        let button = (
            <>
                {this.defaultButton}
            </>
        );

        switch (this.type) {
            case ButtonType.DropdownButton:
                button = (
                    <>
                        {this.dropdownButton}
                    </>
                );
                break;
            case ButtonType.DropdownList:
                button = (
                    <div className={`menuButton ${this.type} ${active}`}
                        style={{ backgroundColor: this.rootDoc.dropDownOpen ? "#aeddf880" : undefined, color: this.rootDoc.dropDownOpen ? "#1c5c96" : "black", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
                        onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}>
                        {/* {toggle} */}
                        {label}
                        {dropdownCaret}
                        {this.rootDoc.dropDownOpen ?
                            <>
                                <div className="menuButton-dropdownList"
                                    style={{ left: 0 }}>
                                    {items}
                                </div>
                                <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
                            </>
                            : null}
                    </div>
                );
                break;
            case ButtonType.ColorButton:
                button = (
                    <div className={`menuButton ${this.type} ${active}`}
                        style={{ opacity: selectedDoc ? 1 : 0.5, color: dark ? "white" : "black", borderBottomLeftRadius: this.dropdown ? 0 : undefined }}
                        onClick={() => this.rootDoc.dropDownOpen = !this.rootDoc.dropDownOpen}
                        onPointerDown={e => e.stopPropagation()}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={dark ? "white" : "black"} />
                        {label}
                        {dropdownCaret}
                        {this.rootDoc.dropDownOpen ?
                            <>
                                <div className="menuButton-dropdownBox"
                                    onPointerDown={e => e.stopPropagation()}
                                    onClick={e => e.stopPropagation()}
                                    style={{ left: 0 }}>
                                    {colorBox((color) => this.setColor(color, StrCast(this.rootDoc.docColor), StrCast(this.rootDoc.userColor)))}
                                </div>
                                <div className="dropbox-background" onClick={(e) => { e.stopPropagation(); this.rootDoc.dropDownOpen = false; }} />
                            </>
                            : null}
                    </div>
                );
                break;
            // case ButtonType.ToggleButton:
            //     button = (
            //         <div className={`menuButton ${this.type}`} style={{ opacity: canClick ? 1 : 0.4, backgroundColor: toggle ? this.backgroundColor : undefined }}>
            //             <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={toggle ? this.color : this.backgroundColor} />
            //             {label}
            //         </div>
            //     );
            //     break;
            case ButtonType.ClickButton:
                button = (
                    <div className={`menuButton ${this.type}`} style={{ color: this.color, backgroundColor: this.backgroundColor, opacity: canClick ? 1 : 0.4 }}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={this.color} />
                        {label}
                    </div>
                );
                break;
            case ButtonType.DoubleButton:
                button = (
                    <div className={`menuButton ${this.type}`} style={{ color: this.color, backgroundColor: this.backgroundColor }}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={this.color} />
                        {label}
                    </div>
                );
                break;
            case ButtonType.MenuButton:
                button = (
                    <div className={`menuButton ${this.type}`} style={{ color: dark ? "white" : "black", backgroundColor: dark ? "black" : "lightgrey" }}>
                        <FontAwesomeIcon className={`fontIconBox-icon-${this.type}`} icon={this.icon} color={dark ? "white" : "black"} />
                        {menuLabel}
                    </div >
                    // <div className={`menuButton ${type}`} style={{ color, backgroundColor }}>
                    //     <FontAwesomeIcon className={`fontIconBox-icon-${type}`} icon={icon} color={color} />
                    //     {label}
                    // </div>
                );
                break;
            default:
                break;
        }

        return !this.layoutDoc.toolTip ? button :
            <Tooltip title={<div className="dash-tooltip">{StrCast(this.layoutDoc.toolTip)}</div>}>
                {button}
            </Tooltip>;
    }
}
