import interact from "interactjs";
import { updateField, VerdocsEndpoint } from "@verdocs/js-sdk";
import { h, Host, Fragment } from "@stencil/core";
import { SettingsIcon } from "../../../utils/Icons";
import { Store } from "../../../utils/Datastore";
/**
 * Display a simple 1-line text input field.
 */
export class VerdocsFieldTextbox {
    constructor() {
        /**
         * Fields may be attached to templates or envelopes, but only template fields may be edited.
         */
        this.source = 'template';
        /**
         * The source template or envelope ID the field is found in.
         */
        this.sourceid = '';
        /**
         * The name of the field to display.
         */
        this.fieldname = '';
        /**
         * Override the field's settings. This is intended to be used during signing when fields are being
         * mutated.
         */
        this.field = null;
        /**
         * If set, overrides the field's settings object. Primarily used to support "preview" modes where all fields are disabled.
         */
        this.disabled = false;
        /**
         * If set, overrides the field's settings object. Primarily used to support "preview" modes where all fields are disabled.
         */
        this.multiline = false;
        /**
         * If set, a settings icon will be displayed on hover. The settings shown allow the field's recipient and other settings to be
         * changed, so it should typically only be enabled in the Builder.
         */
        this.editable = false;
        /**
         * If set, the field may be dragged to a new location. This should only be enabled in the Builder, or for self-placed fields.
         */
        this.moveable = false;
        /**
         * If set, the field is considered "done" and is drawn in a display-final-value state.
         */
        this.done = false;
        /**
         * If set, the field will be be scaled horizontally by this factor.
         */
        this.xscale = 1;
        /**
         * If set, the field will be be scaled vertically by this factor.
         */
        this.yscale = 1;
        /**
         * The page the field is on
         */
        this.pagenumber = 1;
        this.showingProperties = false;
        this.focused = false;
    }
    handleBlur() {
        this.focused = false;
    }
    async focusField() {
        this.inputEl.focus();
        this.focused = true;
    }
    async showSettingsPanel() {
        const settingsPanel = document.getElementById(`verdocs-settings-panel-${this.fieldname}`);
        if (settingsPanel && settingsPanel.showPanel) {
            settingsPanel.showPanel();
        }
    }
    async hideSettingsPanel() {
        const settingsPanel = document.getElementById(`verdocs-settings-panel-${this.fieldname}`);
        if (settingsPanel && settingsPanel.hidePanel) {
            settingsPanel.hidePanel();
        }
        this.showingProperties = false;
    }
    onEditableChanged(newVal, oldVal) {
        // When transitioning out of editable mode (e.g., builder -> preview tab), clear interact bindings
        if (oldVal && !newVal) {
            interact(this.el).unset();
        }
    }
    disconnectedCallback() {
        // Clear any interact.js drag/resize bindings so they don't leak if the DOM element is reused elsewhere
        interact(this.el).unset();
    }
    componentDidRender() {
        interact.dynamicDrop(true);
        if (this.editable) {
            interact(this.el).resizable({
                edges: {
                    top: '.edge-top',
                    left: '.edge-left',
                    bottom: '.edge-bottom',
                    right: '.edge-right',
                },
                modifiers: [
                    interact.modifiers.restrictSize({
                        min: { width: 30, height: 10 },
                    }),
                ],
                listeners: {
                    start: this.handleResizeStart.bind(this),
                    move: this.handleResize.bind(this),
                    end: this.handleResizeEnd.bind(this),
                },
            });
        }
    }
    handleResizeStart(e) {
        e.preventDefault();
        e.stopPropagation();
        e.target.dataset.originalBottom = e.target.style.bottom;
    }
    handleResize(e) {
        let { width, height } = e.rect;
        const dX = e.deltaRect.left;
        const dY = e.deltaRect.bottom;
        const currentLeft = parseFloat(e.target.style.left);
        const currentBottom = parseFloat(e.target.style.bottom);
        width /= this.xscale;
        height /= this.yscale;
        Object.assign(e.target.style, {
            width: `${width}px`,
            height: `${height}px`,
            left: `${currentLeft + dX}px`,
            bottom: `${currentBottom - dY}px`,
        });
    }
    async handleResizeEnd(e) {
        const { sourceid, fieldname } = this;
        const width = Math.round(parseFloat(e.target.style.width));
        let height = Math.round(parseFloat(e.target.style.height));
        if (height < 10) {
            height = 10;
        }
        const multiline = height > 15;
        const newBottom = parseFloat(e.target.style.bottom);
        const originalBottom = parseFloat(e.target.dataset.originalBottom);
        const template = await Store.getTemplate(VerdocsEndpoint.getDefault(), this.sourceid);
        const oldField = template.fields.find(f => f.name === fieldname);
        const y = newBottom !== originalBottom ? newBottom / this.yscale : oldField === null || oldField === void 0 ? void 0 : oldField.y;
        updateField(VerdocsEndpoint.getDefault(), sourceid, fieldname, { width, height, y, multiline })
            .then(async (updatedField) => {
            var _a;
            const template = await Store.getTemplate(VerdocsEndpoint.getDefault(), this.sourceid);
            const newTemplate = JSON.parse(JSON.stringify(template));
            const fieldIndex = newTemplate.fields.findIndex(field => field.name === fieldname);
            if (fieldIndex > -1) {
                newTemplate.fields[fieldIndex] = updatedField;
            }
            Store.updateTemplate(this.sourceid, newTemplate);
            (_a = this.settingsChanged) === null || _a === void 0 ? void 0 : _a.emit({ fieldName: fieldname, field: updatedField });
            Object.assign(e.target.dataset, { x: 0, y: 0, h: 0 });
        })
            .catch(e => console.log('Field update failed', e));
    }
    render() {
        const { source, sourceid, fieldname, editable = false, done = false, disabled = false, focused, xscale = 1, yscale = 1 } = this;
        const { index, field } = Store.getField(source, sourceid, fieldname, this.field);
        let { required = false, placeholder = '', label = '', width = 150, height = 15, readonly = false, default: value = '', multiline = false } = field || {};
        const signerClass = `signer-${(index % 10) + 1}`;
        const small = height < 15;
        // TODO: Consolidate value/defaultValue handling between template and envelope fields.
        if (field === null || field === void 0 ? void 0 : field.value) {
            value = field === null || field === void 0 ? void 0 : field.value;
        }
        // TODO: This is an outdated technique from the old system. We should compute it.
        const maxlength = width / 5;
        if (done) {
            return h(Host, { class: { 'verdocs-field': true, done } }, value);
        }
        return (h(Host, { class: { 'verdocs-field': true, required, disabled, done, focused, small, [signerClass]: true } }, editable && h("div", { class: "edge-top" }), editable && h("div", { class: "edge-right" }), editable && h("div", { class: "edge-left" }), editable && h("div", { class: "edge-bottom" }), label && h("label", null, label), multiline ? (h("textarea", { name: fieldname, required: required, placeholder: placeholder, disabled: readonly || disabled, ref: el => (this.inputEl = el), onFocus: () => (this.focused = true), onBlur: () => (this.focused = false) }, value)) : (h("input", { type: "text", value: value, name: fieldname, required: required, maxlength: maxlength, placeholder: placeholder, disabled: readonly || disabled, ref: el => (this.inputEl = el), onFocus: () => (this.focused = true), onBlur: () => (this.focused = false) })), editable && (h(Fragment, null, h("div", { id: `verdocs-settings-panel-trigger-${fieldname}`, style: { transform: `scale(${Math.floor((1 / xscale) * 1000) / 1000}, ${Math.floor((1 / yscale) * 1000) / 1000})` }, class: "settings-icon", innerHTML: SettingsIcon, onClick: (e) => {
                e.stopPropagation();
                this.showingProperties = !this.showingProperties;
            } }), this.showingProperties && (h("verdocs-portal", { anchor: `verdocs-settings-panel-trigger-${fieldname}`, onClickAway: () => (this.showingProperties = false) }, h("verdocs-template-field-properties", { templateId: sourceid, fieldName: fieldname, onClose: () => this.hideSettingsPanel(), onDelete: () => {
                var _a;
                (_a = this.deleted) === null || _a === void 0 ? void 0 : _a.emit({ fieldName: fieldname });
                return this.hideSettingsPanel();
            }, onSettingsChanged: e => {
                var _a;
                (_a = this.settingsChanged) === null || _a === void 0 ? void 0 : _a.emit(e.detail);
                return this.hideSettingsPanel();
            }, helpText: 'Text boxes may be used to capture simple text input. Participant-entered values will be stored for later retrieval via the "name" field.<br /><br />If marked required, the participant must complete the field before proceeding.' })))))));
    }
    static get is() { return "verdocs-field-textbox"; }
    static get originalStyleUrls() {
        return {
            "$": ["verdocs-field-textbox.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["verdocs-field-textbox.css"]
        };
    }
    static get properties() {
        return {
            "source": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "'template' | 'envelope'",
                    "resolved": "\"envelope\" | \"template\"",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Fields may be attached to templates or envelopes, but only template fields may be edited."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "source",
                "defaultValue": "'template'"
            },
            "sourceid": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The source template or envelope ID the field is found in."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "sourceid",
                "defaultValue": "''"
            },
            "fieldname": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The name of the field to display."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "fieldname",
                "defaultValue": "''"
            },
            "field": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "IEnvelopeField | null | undefined",
                    "resolved": "IEnvelopeField",
                    "references": {
                        "IEnvelopeField": {
                            "location": "import",
                            "path": "@verdocs/js-sdk",
                            "id": "node_modules::IEnvelopeField",
                            "referenceLocation": "IEnvelopeField"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Override the field's settings. This is intended to be used during signing when fields are being\nmutated."
                },
                "getter": false,
                "setter": false,
                "defaultValue": "null"
            },
            "isPreview": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set to true, it will force interact to unset the el, resulting in no dragging the field."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "is-preview"
            },
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set, overrides the field's settings object. Primarily used to support \"preview\" modes where all fields are disabled."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "multiline": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set, overrides the field's settings object. Primarily used to support \"preview\" modes where all fields are disabled."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "multiline",
                "defaultValue": "false"
            },
            "editable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set, a settings icon will be displayed on hover. The settings shown allow the field's recipient and other settings to be\nchanged, so it should typically only be enabled in the Builder."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "editable",
                "defaultValue": "false"
            },
            "moveable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set, the field may be dragged to a new location. This should only be enabled in the Builder, or for self-placed fields."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "moveable",
                "defaultValue": "false"
            },
            "done": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set, the field is considered \"done\" and is drawn in a display-final-value state."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "done",
                "defaultValue": "false"
            },
            "xscale": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set, the field will be be scaled horizontally by this factor."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "xscale",
                "defaultValue": "1"
            },
            "yscale": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If set, the field will be be scaled vertically by this factor."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "yscale",
                "defaultValue": "1"
            },
            "pagenumber": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The page the field is on"
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "pagenumber",
                "defaultValue": "1"
            }
        };
    }
    static get states() {
        return {
            "showingProperties": {},
            "focused": {}
        };
    }
    static get events() {
        return [{
                "method": "settingsChanged",
                "name": "settingsChanged",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Event fired when the field's settings are changed."
                },
                "complexType": {
                    "original": "{fieldName: string; field: ITemplateField}",
                    "resolved": "{ fieldName: string; field: ITemplateField; }",
                    "references": {
                        "ITemplateField": {
                            "location": "import",
                            "path": "@verdocs/js-sdk",
                            "id": "node_modules::ITemplateField",
                            "referenceLocation": "ITemplateField"
                        }
                    }
                }
            }, {
                "method": "deleted",
                "name": "deleted",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Event fired when the field is deleted."
                },
                "complexType": {
                    "original": "{fieldName: string}",
                    "resolved": "{ fieldName: string; }",
                    "references": {}
                }
            }];
    }
    static get methods() {
        return {
            "focusField": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "showSettingsPanel": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            },
            "hideSettingsPanel": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "editable",
                "methodName": "onEditableChanged"
            }];
    }
    static get listeners() {
        return [{
                "name": "blur",
                "method": "handleBlur",
                "target": undefined,
                "capture": true,
                "passive": false
            }];
    }
}
//# sourceMappingURL=verdocs-field-textbox.js.map
