import React = require('react');
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { computed } from 'mobx';
import { observer } from 'mobx-react';
import { DragManager } from '../../../util/DragManager';
import { SnappingManager } from '../../../util/SnappingManager';
import { undoBatch } from '../../../util/UndoManager';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { OpenWhere } from '../../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../../nodes/FieldView';
import { CollectionSchemaView } from './CollectionSchemaView';
import './CollectionSchemaView.scss';
import { SchemaTableCell } from './SchemaTableCell';

@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 schemaView() {
        const vpath = this.props.docViewPath();
        return vpath.length > 1 ? (vpath[vpath.length - 2].ComponentView as CollectionSchemaView) : undefined;
    }

    @computed get schemaDoc() {
        return this.props.ContainingCollectionDoc!;
    }

    @computed get rowIndex() {
        return this.schemaView?.rowIndex(this.rootDoc) ?? -1;
    }

    componentDidMount(): void {
        this.props.setContentView?.(this);
    }

    select = (ctrlKey: boolean, shiftKey: boolean) => {
        if (!this.schemaView) return;
        const lastSelected = Array.from(this.schemaView._selectedDocs).lastElement();
        if (shiftKey && lastSelected) this.schemaView.selectRows(this.rootDoc, lastSelected);
        else {
            this.props.select?.(ctrlKey);
        }
    };

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

    onPointerMove = (e: any) => {
        if (!SnappingManager.GetIsDragging()) return;
        const dragIsRow = DragManager.docsBeingDragged.some(doc => doc.context === this.schemaDoc); //  this.schemaView?._selectedDocs.has(doc) ?? false;

        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.schemaView?.setDropIndex(this.rowIndex);
            } else if (y > halfLine) {
                this._ref.style.borderTop = '0px';
                this._ref.style.borderBottom = `solid 2px ${Colors.MEDIUM_BLUE}`;
                this.schemaView?.setDropIndex(this.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={{ height: CollectionSchemaView._rowHeight, backgroundColor: this.props.isSelected() ? Colors.LIGHT_BLUE : undefined, pointerEvents: this.schemaView?.props.isContentActive() ? 'all' : undefined }}
                onPointerEnter={this.onPointerEnter}
                onPointerLeave={this.onPointerLeave}
                ref={(row: HTMLDivElement | null) => {
                    row && this.schemaView?.addRowRef?.(this.rootDoc, row);
                    this._ref = row;
                }}>
                <div
                    className="row-menu"
                    style={{
                        width: CollectionSchemaView._rowMenuWidth,
                        pointerEvents: !this.props.isContentActive() ? 'none' : undefined,
                    }}>
                    <div
                        className="schema-row-button"
                        onPointerDown={undoBatch(e => {
                            e.stopPropagation();
                            this.props.removeDocument?.(this.rootDoc);
                        })}>
                        <FontAwesomeIcon icon="times" />
                    </div>
                    <div
                        className="schema-row-button"
                        onPointerDown={e => {
                            e.stopPropagation();
                            this.props.addDocTab(this.rootDoc, OpenWhere.addRight);
                        }}>
                        <FontAwesomeIcon icon="external-link-alt" />
                    </div>
                </div>
                <div className="row-cells">
                    {this.schemaView?.columnKeys?.map((key, index) => (
                        <SchemaTableCell
                            key={key}
                            Document={this.rootDoc}
                            schemaView={this.schemaView}
                            fieldKey={key}
                            columnWidth={this.schemaView?.displayColumnWidths[index] ?? CollectionSchemaView._minColWidth}
                            isRowActive={this.props.isContentActive}
                            setColumnValues={(field, value) => this.schemaView?.setColumnValues(field, value) ?? false}
                        />
                    ))}
                </div>
            </div>
        );
    }
}
