import debounce from "lodash/debounce";
import { getSourceItem } from "../../store/index";
import { DRAGG_TEXT } from "../../utils/consts";
import RowOrderService from "./order-row.service";
/**
 * Component for handling row order editor.
 */
export class OrderEditor {
    constructor() {
        this.events = [];
        this.rowMoveFunc = debounce((y) => {
            const rgRow = this.rowOrderService.move(y, this.getData());
            if (rgRow !== null) {
                this.rowDrag.emit(Object.assign(Object.assign({}, rgRow), { rowType: this.rowType }));
            }
        }, 5);
    }
    // #endregion
    // #region Methods
    async dragStart(e) {
        e.originalEvent.preventDefault();
        // extra check if previous ended
        if (this.events.length) {
            this.clearOrder();
        }
        const data = this.getData();
        const cell = this.rowOrderService.startOrder(e.originalEvent, data);
        const pos = this.rowOrderService.getRow(e.originalEvent.y, data);
        const dragStartEvent = this.rowDragStart.emit({
            cell,
            text: DRAGG_TEXT,
            pos,
            event: e.originalEvent,
            rowType: this.rowType,
            model: getSourceItem(this.dataStore, pos.itemIndex),
        });
        if (dragStartEvent.defaultPrevented) {
            return;
        }
        const moveMove = (e) => this.move(e);
        const mouseUp = (e) => this.endOrder(e);
        const mouseLeave = () => this.clearOrder();
        this.events.push({
            name: 'mousemove',
            listener: moveMove,
        }, {
            name: 'mouseup',
            listener: mouseUp,
        }, {
            name: 'mouseleave',
            listener: mouseLeave,
        });
        document.addEventListener('mousemove', moveMove);
        // Action finished inside of the document
        document.addEventListener('mouseup', mouseUp);
        document.addEventListener('mouseleave', mouseLeave);
    }
    async endOrder(e) {
        this.rowOrderService.endOrder(e, this.getData());
        this.clearOrder();
    }
    async clearOrder() {
        this.rowOrderService.clear();
        this.events.forEach(v => document.removeEventListener(v.name, v.listener));
        this.events.length = 0;
        this.rowDragEnd.emit({ rowType: this.rowType });
    }
    // #endregion
    move({ x, y }) {
        this.rowMouseMove.emit({ x, y, rowType: this.rowType });
        this.rowMoveFunc(y);
    }
    connectedCallback() {
        this.rowOrderService = new RowOrderService({
            positionChanged: (from, to) => {
                const dropEvent = this.rowDropped.emit({
                    from,
                    to,
                    rowType: this.rowType,
                });
                if (dropEvent.defaultPrevented) {
                    return;
                }
                this.rowOrderChange.emit(dropEvent.detail);
            },
        });
    }
    getData() {
        return {
            el: this.parent,
            rows: this.dimensionRow.state,
            cols: this.dimensionCol.state,
        };
    }
    static get is() { return "revogr-order-editor"; }
    static get properties() {
        return {
            "parent": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "HTMLElement",
                    "resolved": "HTMLElement",
                    "references": {
                        "HTMLElement": {
                            "location": "global",
                            "id": "global::HTMLElement"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Parent element"
                },
                "getter": false,
                "setter": false
            },
            "dimensionRow": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Observable<DimensionSettingsState>",
                    "resolved": "DimensionSettingsState",
                    "references": {
                        "Observable": {
                            "location": "import",
                            "path": "../../utils",
                            "id": "src/utils/index.ts::Observable",
                            "referenceLocation": "Observable"
                        },
                        "DimensionSettingsState": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionSettingsState",
                            "referenceLocation": "DimensionSettingsState"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Dimension settings Y"
                },
                "getter": false,
                "setter": false
            },
            "dimensionCol": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Observable<DimensionSettingsState>",
                    "resolved": "DimensionSettingsState",
                    "references": {
                        "Observable": {
                            "location": "import",
                            "path": "../../utils",
                            "id": "src/utils/index.ts::Observable",
                            "referenceLocation": "Observable"
                        },
                        "DimensionSettingsState": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionSettingsState",
                            "referenceLocation": "DimensionSettingsState"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Dimension settings X"
                },
                "getter": false,
                "setter": false
            },
            "dataStore": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "Observable<DSourceState<DataType, DimensionRows>>",
                    "resolved": "\"rgRow\" | \"rowPinEnd\" | \"rowPinStart\" | D | K",
                    "references": {
                        "Observable": {
                            "location": "import",
                            "path": "../../utils",
                            "id": "src/utils/index.ts::Observable",
                            "referenceLocation": "Observable"
                        },
                        "DSourceState": {
                            "location": "import",
                            "path": "@store",
                            "id": "src/store/index.ts::DSourceState",
                            "referenceLocation": "DSourceState"
                        },
                        "DataType": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DataType",
                            "referenceLocation": "DataType"
                        },
                        "DimensionRows": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionRows",
                            "referenceLocation": "DimensionRows"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Static stores, not expected to change during component lifetime"
                },
                "getter": false,
                "setter": false
            },
            "rowType": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "DimensionRows",
                    "resolved": "\"rgRow\" | \"rowPinEnd\" | \"rowPinStart\"",
                    "references": {
                        "DimensionRows": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionRows",
                            "referenceLocation": "DimensionRows"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "row-type"
            }
        };
    }
    static get events() {
        return [{
                "method": "rowDragStart",
                "name": "rowdragstartinit",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Row drag started"
                },
                "complexType": {
                    "original": "RowDragStartDetails",
                    "resolved": "TModel",
                    "references": {
                        "RowDragStartDetails": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::RowDragStartDetails",
                            "referenceLocation": "RowDragStartDetails"
                        }
                    }
                }
            }, {
                "method": "rowDragEnd",
                "name": "rowdragendinit",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Row drag ended started"
                },
                "complexType": {
                    "original": "{ rowType: DimensionRows }",
                    "resolved": "{ rowType: DimensionRows; }",
                    "references": {
                        "DimensionRows": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionRows",
                            "referenceLocation": "DimensionRows"
                        }
                    }
                }
            }, {
                "method": "rowDrag",
                "name": "rowdragmoveinit",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Row move started"
                },
                "complexType": {
                    "original": "PositionItem & { rowType: DimensionRows }",
                    "resolved": "PositionItem & { rowType: DimensionRows; }",
                    "references": {
                        "PositionItem": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::PositionItem",
                            "referenceLocation": "PositionItem"
                        },
                        "DimensionRows": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionRows",
                            "referenceLocation": "DimensionRows"
                        }
                    }
                }
            }, {
                "method": "rowMouseMove",
                "name": "rowdragmousemove",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Row mouse move started"
                },
                "complexType": {
                    "original": "Cell & { rowType: DimensionRows }",
                    "resolved": "Cell & { rowType: DimensionRows; }",
                    "references": {
                        "Cell": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::Cell",
                            "referenceLocation": "Cell"
                        },
                        "DimensionRows": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionRows",
                            "referenceLocation": "DimensionRows"
                        }
                    }
                }
            }, {
                "method": "rowDropped",
                "name": "rowdropinit",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Row dragged, new range ready to be applied"
                },
                "complexType": {
                    "original": "{\n    from: number;\n    to: number;\n    rowType: DimensionRows;\n  }",
                    "resolved": "{ from: number; to: number; rowType: DimensionRows; }",
                    "references": {
                        "DimensionRows": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionRows",
                            "referenceLocation": "DimensionRows"
                        }
                    }
                }
            }, {
                "method": "rowOrderChange",
                "name": "roworderchange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Row drag ended finished. Time to apply data"
                },
                "complexType": {
                    "original": "{\n    from: number;\n    to: number;\n    rowType: DimensionRows;\n  }",
                    "resolved": "{ from: number; to: number; rowType: DimensionRows; }",
                    "references": {
                        "DimensionRows": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DimensionRows",
                            "referenceLocation": "DimensionRows"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "dragStart": {
                "complexType": {
                    "signature": "(e: DragStartEvent) => Promise<void>",
                    "parameters": [{
                            "name": "e",
                            "type": "DragStartEvent<DataType<any, ColumnProp>, ColumnRegular<ColumnProp, DataType<any, ColumnProp>>>",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "DragStartEvent": {
                            "location": "import",
                            "path": "@type",
                            "id": "src/types/index.ts::DragStartEvent",
                            "referenceLocation": "DragStartEvent"
                        },
                        "MouseEvent": {
                            "location": "global",
                            "id": "global::MouseEvent"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "endOrder": {
                "complexType": {
                    "signature": "(e: MouseEvent) => Promise<void>",
                    "parameters": [{
                            "name": "e",
                            "type": "MouseEvent",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "MouseEvent": {
                            "location": "global",
                            "id": "global::MouseEvent"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "clearOrder": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            }
        };
    }
}
