import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, observable } from 'mobx';
import { observer } from 'mobx-react';
import { emptyFunction, setupMoveUpEvents } from '../../../../Utils';
import './CollectionSchemaView.scss';
import { ColumnType } from './CollectionSchemaView';
import { Colors } from 'browndash-components';

export interface SchemaColumnHeaderProps {
    columnKeys: string[];
    columnWidths: number[];
    columnIndex: number;
    possibleKeys: string[];
    sortField: string;
    sortDesc: boolean;
    setSort: (field: string, desc: boolean) => void;
    changeColumnKey: (index: number, newKey: string, defaultVal?: any) => void;
    addColumn: (index: number, key: string, defaultVal?: any) => void;
    removeColumn: (index: number) => void;
    resizeColumn: (e: any, index: number, left: boolean) => void;
    // dragColumn: (e: any, index: number) => boolean;
}

@observer
export class SchemaColumnHeader extends React.Component<SchemaColumnHeaderProps> {
    @observable _menuVisible: boolean = false;
    @observable _makeNewField: boolean = false;
    @observable _newFieldType: ColumnType = ColumnType.Number;
    @observable _newFieldDefault: any = 0;
    @observable _newFieldWarning: string = '';
    @observable _menuValue: string = '';
    @observable _menuOptions: string[] = [];
    @observable _filterVisible: boolean = false;
    private _makeNewColumn = false;

    @computed get fieldKey() {
        return this.props.columnKeys[this.props.columnIndex];
    }

    @action
    sortClicked = (e: React.PointerEvent) => {
        e.stopPropagation();
        e.preventDefault();
        if (this.props.sortField == this.fieldKey) {
            this.props.setSort(this.fieldKey, !this.props.sortDesc);
        } else {
            this.props.setSort(this.fieldKey, false);
        }
    };

    @computed get fieldDefaultInput() {
        switch (this._newFieldType) {
            case ColumnType.Number:
                return <input type="number" name="" id="" value={this._newFieldDefault ?? 0} onPointerDown={e => e.stopPropagation()} onChange={action(e => (this._newFieldDefault = e.target.value))} />;
            case ColumnType.Boolean:
                return (
                    <>
                        <input type="checkbox" name="" id="" value={this._newFieldDefault} onPointerDown={e => e.stopPropagation()} onChange={action(e => (this._newFieldDefault = e.target.checked))} />
                        {this._newFieldDefault ? 'true' : 'false'}
                    </>
                );
            case ColumnType.String:
                return <input type="text" name="" id="" value={this._newFieldDefault ?? ''} onPointerDown={e => e.stopPropagation()} onChange={action(e => (this._newFieldDefault = e.target.value))} />;
        }
    }

    @computed get renderColumnMenu() {
        return (
            <div className="schema-column-menu">
                <input className="schema-key-search-input" type="text" value={this._menuValue} onKeyDown={this.onSearchKeyDown} onChange={this.updateKeySearch} onPointerDown={e => e.stopPropagation()} />
                {this._makeNewField ? (
                    <div className="schema-new-key-options">
                        <div className="schema-key-type-option">
                            <input
                                type="radio"
                                name="newFieldType"
                                id=""
                                checked={this._newFieldType == ColumnType.Number}
                                onChange={action(() => {
                                    this._newFieldType = ColumnType.Number;
                                    this._newFieldDefault = 0;
                                })}
                            />
                            number
                        </div>
                        <div className="schema-key-type-option">
                            <input
                                type="radio"
                                name="newFieldType"
                                id=""
                                checked={this._newFieldType == ColumnType.Boolean}
                                onChange={action(() => {
                                    this._newFieldType = ColumnType.Boolean;
                                    this._newFieldDefault = false;
                                })}
                            />
                            boolean
                        </div>
                        <div className="schema-key-type-option">
                            <input
                                type="radio"
                                name="newFieldType"
                                id=""
                                checked={this._newFieldType == ColumnType.String}
                                onChange={action(() => {
                                    this._newFieldType = ColumnType.String;
                                    this._newFieldDefault = '';
                                })}
                            />
                            string
                        </div>
                        <div className="schema-key-default-val">value: {this.fieldDefaultInput}</div>
                        <div className="schema-key-warning">{this._newFieldWarning}</div>
                        <div
                            className="schema-column-menu-button"
                            onPointerDown={action(e => {
                                if (this.props.possibleKeys.includes(this._menuValue)) {
                                    this._newFieldWarning = 'Field already exists';
                                } else if (this._menuValue.length === 0) {
                                    this._newFieldWarning = 'Field cannot be an empty string';
                                } else {
                                    this.setKey(this._menuValue, this._newFieldDefault);
                                }
                            })}>
                            done
                        </div>
                    </div>
                ) : (
                    <div className="schema-key-search">
                        <div
                            className="schema-column-menu-button"
                            onPointerDown={action(e => {
                                e.stopPropagation();
                                this._makeNewField = true;
                            })}>
                            + new field
                        </div>
                        <div className="schema-key-list">
                            {this._menuOptions.map(key => (
                                <div
                                    className="schema-key-search-result"
                                    onPointerDown={e => {
                                        e.stopPropagation();
                                        this.setKey(key);
                                    }}>
                                    {key}
                                </div>
                            ))}
                        </div>
                    </div>
                )}
            </div>
        );
    }

    @computed get columnFilterMenu() {
        return (
            <div className="schema-column-menu">
                <input className="schema-key-search-input" type="text" value={this._menuValue} onKeyDown={this.onSearchKeyDown} onChange={this.updateKeySearch} onPointerDown={e => e.stopPropagation()} />
            </div>
        );
    }

    onSearchKeyDown = (e: React.KeyboardEvent) => {
        switch (e.key) {
            case 'Enter':
                this.setKey(this._menuOptions.length > 0 && this._menuValue.length > 0 ? this._menuOptions[0] : this._menuValue);
                break;
            case 'Escape':
                this.toggleColumnMenu();
                break;
        }
    };

    @action
    setKey = (key: string, defaultVal?: any) => {
        if (this._makeNewColumn) {
            this.props.addColumn(this.props.columnIndex, key, defaultVal);
        } else {
            this.props.changeColumnKey(this.props.columnIndex, key, defaultVal);
        }
        this.toggleColumnMenu();
    };

    @action
    updateKeySearch = (e: React.ChangeEvent<HTMLInputElement>) => {
        this._menuValue = e.target.value;
        this._menuOptions = this.props.possibleKeys.filter(value => value.toLowerCase().includes(this._menuValue.toLowerCase()));
    };

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

    //     setupMoveUpEvents(this, e, e => this.props.dragColumn(e, this.props.columnIndex), emptyFunction, emptyFunction);
    // };

    @action
    toggleColumnMenu = (newCol?: boolean) => {
        this._makeNewColumn = false;
        if (this._menuVisible) {
            this._menuVisible = false;
        } else {
            this._filterVisible = false;
            this._menuVisible = true;
            this._menuValue = '';
            this._menuOptions = this.props.possibleKeys;
            this._makeNewField = false;
            this._newFieldWarning = '';
            this._makeNewField = false;
            if (newCol) {
                this._makeNewColumn = true;
            }
        }
    };

    @action
    toggleFilterMenu = () => {
        console.log(this._filterVisible);
        if (this._filterVisible) {
            this._filterVisible = false;
        } else {
            this._filterVisible = true;
            this._menuVisible = false;
        }
    };

    render() {
        return (
            <div className="schema-column-header" style={{ width: this.props.columnWidths[this.props.columnIndex] }}>
                <div className="schema-column-resizer left" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex, true)}></div>
                <div className="schema-column-title">{this.fieldKey}</div>

                <div className="schema-header-menu">
                    <div
                        className="schema-header-button"
                        onPointerDown={e => {
                            this.toggleColumnMenu();
                        }}>
                        <FontAwesomeIcon icon="pencil-alt" />
                    </div>
                    <div
                        className="schema-header-button"
                        onPointerDown={e => {
                            this.toggleColumnMenu(true);
                        }}>
                        <FontAwesomeIcon icon="plus" />
                    </div>
                    <div
                        className="schema-header-button"
                        onPointerDown={e => {
                            this.props.removeColumn(this.props.columnIndex);
                        }}>
                        <FontAwesomeIcon icon="trash" />
                    </div>
                    <div className="schema-header-button" onPointerDown={this.sortClicked} style={this.props.sortField == this.fieldKey ? { backgroundColor: Colors.MEDIUM_BLUE } : {}}>
                        <FontAwesomeIcon icon="caret-right" style={this.props.sortField == this.fieldKey ? { transform: `rotate(${this.props.sortDesc ? '270deg' : '90deg'})` } : {}} />
                    </div>
                    <div className="schema-header-button" onPointerDown={e => this.toggleFilterMenu()}>
                        <FontAwesomeIcon icon="filter" />
                    </div>
                </div>

                <div className="schema-column-resizer right" onPointerDown={e => this.props.resizeColumn(e, this.props.columnIndex, false)}></div>

                {this._menuVisible && this.renderColumnMenu}
                {this._filterVisible && this.columnFilterMenu}
            </div>
        );
    }
}
