import { __awaiter } from "tslib";
import { Component, ChangeDetectionStrategy, ChangeDetectorRef, ElementRef } from '@angular/core';
import { CommonModule } from '@angular/common';
import { CodeEditorDialogComponent, TypescriptLanguageModel } from '@anglr/dynamic';
import { RelationsNodeBase, RelationNodeOutputSAComponent, RelationsNodeHeaderSAComponent, RelationNodeInputSAComponent } from '@anglr/dynamic/relations-editor';
import { ConfigureNodeEndpointSAComponent } from '@anglr/dynamic/layout-relations';
import { TitledDialogService } from '@anglr/common/material';
import { FirstUppercaseLocalizeSAPipe } from '@anglr/common';
import { generateId } from '@jscrpt/common';
import { lastValueFrom } from '@jscrpt/common/rxjs';
import typings from '!!raw-loader?esModule!@anglr/dynamic/typings/state';
import { languages } from 'monaco-editor';
import * as i0 from "@angular/core";
import * as i1 from "@anglr/common/material";
import * as i2 from "@angular/common";
languages.typescript.typescriptDefaults.addExtraLib(typings, 'file:///node_modules/@types/state/index.d.ts');
/**
 * Relations node component for state
 */
export class StateNodeSAComponent extends RelationsNodeBase {
    //######################### protected properties - template bindings #########################
    /**
     * Gets added input function names
     */
    get inputFunctions() {
        var _a, _b;
        var _c;
        if (!this.metadata) {
            return [];
        }
        (_a = (_c = this.metadata).relationsOptions) !== null && _a !== void 0 ? _a : (_c.relationsOptions = {
            inputFunctions: {},
        });
        return Object.keys((_b = this.metadata.relationsOptions.inputFunctions) !== null && _b !== void 0 ? _b : {});
    }
    //######################### constructor #########################
    constructor(changeDetector, element, dialog) {
        super(changeDetector, element);
        this.dialog = dialog;
    }
    //######################### protected methods - template bindings #########################
    /**
     * Adds new input function
     */
    addInputFunc() {
        var _a, _b, _c;
        var _d, _e;
        return __awaiter(this, void 0, void 0, function* () {
            const inputFunc = {
                id: generateId(12),
                code: null,
            };
            const name = {
                name: `inputFunc${this.inputFunctions.length + 1}`,
                defaultValue: null,
                noDefaultValue: true,
                skipInit: false,
            };
            if (yield this.configureEndpoint(name)) {
                if (!((_a = this.metadata) === null || _a === void 0 ? void 0 : _a.relationsOptions) || !this.metadata.nodeMetadata) {
                    return;
                }
                (_b = (_d = this.metadata.relationsOptions).inputFunctions) !== null && _b !== void 0 ? _b : (_d.inputFunctions = {});
                this.metadata.relationsOptions.inputFunctions[name.name] = inputFunc;
                (_c = (_e = this.metadata.nodeMetadata).options) !== null && _c !== void 0 ? _c : (_e.options = {
                    contents: {}
                });
                if (this.metadata.nodeMetadata.options.contents) {
                    this.metadata.nodeMetadata.options.contents[name.name] = '';
                }
                this.history.getNewState();
            }
        });
    }
    /**
     * Removes input function
     * @param name - Name of input function to be removed
     */
    removeInputFunc(name) {
        var _a, _b, _c, _d;
        if (((_b = (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.relationsOptions) === null || _b === void 0 ? void 0 : _b.inputFunctions) && name in this.metadata.relationsOptions.inputFunctions) {
            delete this.metadata.relationsOptions.inputFunctions[name];
            if ((_d = (_c = this.metadata.nodeMetadata) === null || _c === void 0 ? void 0 : _c.options) === null || _d === void 0 ? void 0 : _d.contents) {
                delete this.metadata.nodeMetadata.options.contents[name];
            }
            this.history.getNewState();
        }
    }
    /**
     * Renames input func
     * @param name - Allows renaming of input func
     */
    rename(name) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.configureEndpoint({
                name,
                defaultValue: null,
                noDefaultValue: true,
                skipInit: false,
            });
            this.changeDetector.detectChanges();
        });
    }
    /**
     * Configures endpoint
     * @param endpoint - Endpoint to be configured
     */
    configureEndpoint(endpoint) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        return __awaiter(this, void 0, void 0, function* () {
            const copy = JSON.parse(JSON.stringify(endpoint));
            const result = yield lastValueFrom(this.dialog.open(ConfigureNodeEndpointSAComponent, {
                title: 'configure input function',
                width: '60vw',
                data: copy,
            }).afterClosed());
            //rename
            if (result) {
                if (((_c = (_b = (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.relationsOptions) === null || _b === void 0 ? void 0 : _b.inputFunctions) === null || _c === void 0 ? void 0 : _c[endpoint.name]) && (((_f = (_e = (_d = this.metadata.nodeMetadata) === null || _d === void 0 ? void 0 : _d.options) === null || _e === void 0 ? void 0 : _e.contents) === null || _f === void 0 ? void 0 : _f[endpoint.name]) === '' || ((_j = (_h = (_g = this.metadata.nodeMetadata) === null || _g === void 0 ? void 0 : _g.options) === null || _h === void 0 ? void 0 : _h.contents) === null || _j === void 0 ? void 0 : _j[endpoint.name]))) {
                    this.metadata.relationsOptions.inputFunctions[copy.name] = this.metadata.relationsOptions.inputFunctions[endpoint.name];
                    delete this.metadata.relationsOptions.inputFunctions[endpoint.name];
                    this.metadata.nodeMetadata.options.contents[copy.name] = this.metadata.nodeMetadata.options.contents[endpoint.name];
                    delete this.metadata.nodeMetadata.options.contents[endpoint.name];
                    this.history.getNewState();
                }
                else {
                    endpoint.name = copy.name;
                }
            }
            return result !== null && result !== void 0 ? result : false;
        });
    }
    /**
     * Shows code editor
     * @param name - Name of input func
     */
    showCodeEditor(name) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j;
        var _k, _l, _m;
        return __awaiter(this, void 0, void 0, function* () {
            const result = yield lastValueFrom(this.dialog.open(CodeEditorDialogComponent, {
                title: 'Code editor',
                width: '75vw',
                height: '75vh',
                data: {
                    content: (_e = (_d = (_c = (_b = (_a = this.metadata) === null || _a === void 0 ? void 0 : _a.nodeMetadata) === null || _b === void 0 ? void 0 : _b.options) === null || _c === void 0 ? void 0 : _c.contents) === null || _d === void 0 ? void 0 : _d[name]) !== null && _e !== void 0 ? _e : '',
                    languageModel: TypescriptLanguageModel(`import {InputFunction} from 'state';

/**
 * Input function that handles incoming data and can change state
 */
const inputFunc: InputFunction<any, any> = function(_data)
{
};

export default inputFunc;

`),
                }
            }).afterClosed());
            if (!((_f = this.metadata) === null || _f === void 0 ? void 0 : _f.relationsOptions) || !result || !this.metadata.nodeMetadata) {
                return;
            }
            (_g = (_k = this.metadata.relationsOptions).inputFunctions) !== null && _g !== void 0 ? _g : (_k.inputFunctions = {});
            (_h = (_l = this.metadata.nodeMetadata).options) !== null && _h !== void 0 ? _h : (_l.options = {
                contents: {}
            });
            (_j = (_m = this.metadata.nodeMetadata.options).contents) !== null && _j !== void 0 ? _j : (_m.contents = {});
            this.metadata.relationsOptions.inputFunctions[name].code = result.code;
            this.metadata.nodeMetadata.options.contents[name] = result.content;
            this.history.getNewState();
        });
    }
}
StateNodeSAComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: StateNodeSAComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i1.TitledDialogService }], target: i0.ɵɵFactoryTarget.Component });
StateNodeSAComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.4", type: StateNodeSAComponent, isStandalone: true, selector: "state-node", usesInheritance: true, ngImport: i0, template: "<relations-node-header [parent]=\"this\" [destroySubject]=\"destroySubject\" [name]=\"'state'|firstUppercaseLocalize\"></relations-node-header>\n\n<div class=\"node-content\">\n    <div class=\"inputs-outputs\">\n        <div class=\"inputs\">\n            <div class=\"input\">\n                <relation-node-input [parentCoordiantes]=\"nodePosition\" [zoomLevel]=\"zoomLevel\" name=\"initState\" [parent]=\"this\"></relation-node-input>\n                <div>{{'init state'|firstUppercaseLocalize}}</div>\n            </div>\n\n            <div class=\"input\" *ngFor=\"let inputFunc of inputFunctions\">\n                <relation-node-input [parentCoordiantes]=\"nodePosition\" [zoomLevel]=\"zoomLevel\" [name]=\"inputFunc\" [parent]=\"this\"></relation-node-input>\n\n                <div class=\"dynamic-flex-row\">\n                    <div>{{inputFunc}}</div>\n\n                    <button type=\"button\" class=\"dynamic-btn-icon dynamic-margin-horizontal-extra-small\" (click)=\"$event.preventDefault(); $event.stopPropagation(); rename(inputFunc)\">\n                        <span class=\"fas fa-pen\"></span>\n                    </button>\n\n                    <button type=\"button\" class=\"dynamic-btn-icon dynamic-margin-horizontal-extra-small\" (click)=\"$event.preventDefault(); $event.stopPropagation(); showCodeEditor(inputFunc)\">\n                        <span class=\"fas fa-code\"></span>\n                    </button>\n\n                    <button type=\"button\" class=\"dynamic-btn-icon\" (click)=\"$event.preventDefault(); $event.stopPropagation(); removeInputFunc(inputFunc)\">\n                        <span class=\"fas fa-times\"></span>\n                    </button>\n                </div>\n            </div>\n\n            <div class=\"dynamic-flex-row\">\n                <button type=\"button\" class=\"dynamic-btn-icon dynamic-margin-left-extra-small\" (click)=\"$event.preventDefault(); $event.stopPropagation(); addInputFunc()\">\n                    <span class=\"fas fa-plus\"></span>\n                </button>\n            </div>\n        </div>\n\n        <div class=\"outputs\">\n            <div class=\"output\">\n                <div>{{'state'|firstUppercaseLocalize}}</div>\n                <relation-node-output [parentCoordiantes]=\"nodePosition\" [zoomLevel]=\"zoomLevel\" name=\"state\" [parent]=\"this\"></relation-node-output>\n            </div>\n        </div>\n    </div>\n</div>", dependencies: [{ kind: "component", type: RelationsNodeHeaderSAComponent, selector: "relations-node-header", inputs: ["parent", "destroySubject", "name"] }, { kind: "component", type: RelationNodeInputSAComponent, selector: "relation-node-input" }, { kind: "component", type: RelationNodeOutputSAComponent, selector: "relation-node-output" }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: FirstUppercaseLocalizeSAPipe, name: "firstUppercaseLocalize" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.4", ngImport: i0, type: StateNodeSAComponent, decorators: [{
            type: Component,
            args: [{ selector: 'state-node', standalone: true, imports: [
                        RelationsNodeHeaderSAComponent,
                        RelationNodeInputSAComponent,
                        RelationNodeOutputSAComponent,
                        CommonModule,
                        FirstUppercaseLocalizeSAPipe,
                    ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<relations-node-header [parent]=\"this\" [destroySubject]=\"destroySubject\" [name]=\"'state'|firstUppercaseLocalize\"></relations-node-header>\n\n<div class=\"node-content\">\n    <div class=\"inputs-outputs\">\n        <div class=\"inputs\">\n            <div class=\"input\">\n                <relation-node-input [parentCoordiantes]=\"nodePosition\" [zoomLevel]=\"zoomLevel\" name=\"initState\" [parent]=\"this\"></relation-node-input>\n                <div>{{'init state'|firstUppercaseLocalize}}</div>\n            </div>\n\n            <div class=\"input\" *ngFor=\"let inputFunc of inputFunctions\">\n                <relation-node-input [parentCoordiantes]=\"nodePosition\" [zoomLevel]=\"zoomLevel\" [name]=\"inputFunc\" [parent]=\"this\"></relation-node-input>\n\n                <div class=\"dynamic-flex-row\">\n                    <div>{{inputFunc}}</div>\n\n                    <button type=\"button\" class=\"dynamic-btn-icon dynamic-margin-horizontal-extra-small\" (click)=\"$event.preventDefault(); $event.stopPropagation(); rename(inputFunc)\">\n                        <span class=\"fas fa-pen\"></span>\n                    </button>\n\n                    <button type=\"button\" class=\"dynamic-btn-icon dynamic-margin-horizontal-extra-small\" (click)=\"$event.preventDefault(); $event.stopPropagation(); showCodeEditor(inputFunc)\">\n                        <span class=\"fas fa-code\"></span>\n                    </button>\n\n                    <button type=\"button\" class=\"dynamic-btn-icon\" (click)=\"$event.preventDefault(); $event.stopPropagation(); removeInputFunc(inputFunc)\">\n                        <span class=\"fas fa-times\"></span>\n                    </button>\n                </div>\n            </div>\n\n            <div class=\"dynamic-flex-row\">\n                <button type=\"button\" class=\"dynamic-btn-icon dynamic-margin-left-extra-small\" (click)=\"$event.preventDefault(); $event.stopPropagation(); addInputFunc()\">\n                    <span class=\"fas fa-plus\"></span>\n                </button>\n            </div>\n        </div>\n\n        <div class=\"outputs\">\n            <div class=\"output\">\n                <div>{{'state'|firstUppercaseLocalize}}</div>\n                <relation-node-output [parentCoordiantes]=\"nodePosition\" [zoomLevel]=\"zoomLevel\" name=\"state\" [parent]=\"this\"></relation-node-output>\n            </div>\n        </div>\n    </div>\n</div>" }]
        }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.TitledDialogService }] });
//# sourceMappingURL=stateNode.component.js.map