import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, computed, ObservableMap, ObservableSet } from 'mobx';
import { observer } from 'mobx-react';
import { Doc, StrListCast } from '../../../../fields/Doc';
import { undoBatch } from '../../../util/UndoManager';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { FieldView, FieldViewProps } from '../../nodes/FieldView';
import './CollectionSchemaView.scss';
import { SchemaTableCell } from './SchemaTableCell';
import { emptyFunction, setupMoveUpEvents } from '../../../../Utils';
import { DragManager } from '../../../util/DragManager';
import { OpenWhere } from '../../nodes/DocumentView';
import { Cast } from '../../../../fields/Types';
import { listSpec } from '../../../../fields/Schema';
import { CollectionSchemaView } from './CollectionSchemaView';

export interface SchemaRowBoxProps extends FieldViewProps {
    rowIndex: number;
    columnKeys: string[];
    columnWidths: number[];
    rowMenuWidth: number;
    selectedDocs: ObservableSet<Doc>;
    selectRow: (e: any, doc: Doc, ref: HTMLDivElement, index: number) => void;
    startDrag: (e: any, doc: Doc, ref: HTMLDivElement, index: number) => boolean;
    dragging: boolean;
    dropIndex: (index: number) => void;
    addRowRef: (doc: Doc, ref: HTMLDivElement) => void;
}

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

    private _ref: HTMLDivElement | null = null;

    bounds = () => this._ref?.getBoundingClientRect();

    @computed get columnKeys() {
        return StrListCast(this.props.ContainingCollectionDoc?.columnKeys);
    }

    @computed get storedColumnWidths() {
        let widths = Cast(
            this.props.ContainingCollectionDoc?.columnWidths,
            listSpec('number'),
            this.columnKeys.map(() => (this.props.PanelWidth() - CollectionSchemaView._rowMenuWidth) / this.columnKeys.length)
        );

        const totalWidth = widths.reduce((sum, width) => sum + width, 0);
        if (totalWidth !== this.props.PanelWidth() - CollectionSchemaView._rowMenuWidth) {
            widths = widths.map(w => {
                const proportion = w / totalWidth;
                return proportion * (this.props.PanelWidth() - CollectionSchemaView._rowMenuWidth);
            });
        }

        return widths;
    }

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

        // setupMoveUpEvents(
        //     this,
        //     e,
        //     e => this.props.startDrag(e, this.props.Document, this._ref!, this.props.rowIndex),
        //     emptyFunction,
        //     e => this.props.selectRow(e, this.props.Document, this._ref!, this.props.rowIndex)
        // );
    };

    onPointerEnter = (e: any) => {
        // if (!this.props.dragging) return;
        document.removeEventListener('pointermove', this.onPointerMove);
        document.addEventListener('pointermove', this.onPointerMove);
    };

    onPointerMove = (e: any) => {
        // if (!this.props.dragging) return;
        let dragIsRow: boolean = true;
        DragManager.docsBeingDragged.forEach(doc => {
            // dragIsRow = this.props.selectedDocs.has(doc);
        });
        if (this._ref && dragIsRow) {
            const rect = this._ref.getBoundingClientRect();
            const y = e.clientY - rect.top; //y position within the element.
            const height = this._ref.clientHeight;
            const halfLine = height / 2;
            if (y <= halfLine) {
                this._ref.style.borderTop = `solid 2px ${Colors.MEDIUM_BLUE}`;
                this._ref.style.borderBottom = '0px';
                // this.props.dropIndex(this.props.rowIndex);
            } else if (y > halfLine) {
                this._ref.style.borderTop = '0px';
                this._ref.style.borderBottom = `solid 2px ${Colors.MEDIUM_BLUE}`;
                // this.props.dropIndex(this.props.rowIndex + 1);
            }
        }
    };

    onPointerLeave = (e: any) => {
        if (this._ref) {
            this._ref.style.borderTop = '0px';
            this._ref.style.borderBottom = '0px';
        }
        document.removeEventListener('pointermove', this.onPointerMove);
    };

    render() {
        return (
            <div
                className="schema-row"
                style={this.props.isSelected() ? { backgroundColor: Colors.LIGHT_BLUE } : {}}
                // style={this.isSelected() ? { backgroundColor: Colors.LIGHT_BLUE, opacity: this.props.dragging ? 0.5 : 1 } : {}}
                // onPointerDown={this.onRowPointerDown}
                // onPointerEnter={this.onPointerEnter}
                onPointerLeave={this.onPointerLeave}
                ref={(row: HTMLDivElement | null) => {
                    // row && this.props.addRowRef(this.props.Document, row);
                    this._ref = row;
                }}>
                <div
                    className="row-menu"
                    style={
                        {
                            /* width: this.props.rowMenuWidth */
                        }
                    }>
                    <div
                        className="schema-row-button"
                        onPointerDown={undoBatch(e => {
                            e.stopPropagation();
                            this.props.removeDocument?.(this.props.Document);
                        })}>
                        <FontAwesomeIcon icon="times" />
                    </div>
                    <div
                        className="schema-row-button"
                        onPointerDown={e => {
                            e.stopPropagation();
                            this.props.addDocTab(this.props.Document, OpenWhere.addRight);
                        }}>
                        <FontAwesomeIcon icon="external-link-alt" />
                    </div>
                </div>
                <div className="row-cells">
                    {this.columnKeys.map((key, index) => (
                        <SchemaTableCell key={key} Document={this.props.Document} fieldKey={key} columnWidth={this.storedColumnWidths[index]} />
                    ))}
                </div>
            </div>
        );
    }
}
