import {Component, Input, OnInit} from "@angular/core";
import {ComponentLifecycleEventEmitter, Payload, TupleSelector} from "@synerty/vortexjs";
import {PeekCanvasEditor} from "../canvas/PeekCanvasEditor.web";
import {PrivateDiagramCoordSetService} from "@peek/peek_plugin_diagram/_private/services/PrivateDiagramCoordSetService";
import {DiagramCoordSetService} from "@peek/peek_plugin_diagram/DiagramCoordSetService";
import {ModelCoordSet} from "@peek/peek_plugin_diagram/_private/tuples/ModelCoordSet";
import {GroupDispsTuple} from "@peek/peek_plugin_diagram/_private/tuples/GroupDispsTuple";
import {PrivateDiagramTupleService} from "@peek/peek_plugin_diagram/_private/services/PrivateDiagramTupleService";
import {Subject} from "rxjs";
import {PrivateDiagramGridLoaderServiceA} from "@peek/peek_plugin_diagram/_private/grid-loader/PrivateDiagramGridLoaderServiceA";
import {GridTuple} from "@peek/peek_plugin_diagram/_private/grid-loader/GridTuple";
import {PrivateDiagramLookupService} from "@peek/peek_plugin_diagram/_private/services/PrivateDiagramLookupService";
import {LinkedGrid} from "../cache/LinkedGrid.web";
import {DispEdgeTemplate, DispEdgeTemplateT} from "../canvas-shapes/DispEdgeTemplate";
import {PeekCanvasEdgeTemplatePropsContext} from "../canvas/PeekCanvasEdgeTemplatePropsContext";
import {DispGroup} from "../canvas-shapes/DispGroup";


@Component({
    selector: 'pl-diagram-edit-props-edge-template',
    templateUrl: 'edit-props-edge-template.component.html',
    styleUrls: ['edit-props-edge-template.component.scss'],
    moduleId: module.id
})
export class EditPropsEdgeTemplateComponent extends ComponentLifecycleEventEmitter
    implements OnInit {

    @Input("canvasEditor")
    canvasEditor: PeekCanvasEditor;

    context: PeekCanvasEdgeTemplatePropsContext;

    private coordSetCache: PrivateDiagramCoordSetService;

    templateCoordSets: ModelCoordSet[] = [];
    selectedCoordSetId: number = null;

    edgeTemplates: DispEdgeTemplateT[] = [];
    selectedEdgeTemplate = null;

    private unsubSubject = new Subject<void>();

    coordSet: ModelCoordSet = new ModelCoordSet();

    constructor(private tupleService: PrivateDiagramTupleService,
                abstractCoordSetCache: DiagramCoordSetService,
                private gridLoader: PrivateDiagramGridLoaderServiceA,
                private lookupService: PrivateDiagramLookupService) {
        super();
        this.coordSetCache = <PrivateDiagramCoordSetService>abstractCoordSetCache;

    }

    ngOnInit() {
        this.templateCoordSets = [];

        let coordSets = this.coordSetCache
            .coordSets(this.canvasEditor.branchContext.modelSetKey);


        for (let coordSet of coordSets) {
            if (coordSet.id === this.canvasEditor.coordSetId) {
                this.coordSet = coordSet;
                break;
            }
        }

        for (let coordSet of coordSets) {
            if (coordSet.edgeTemplatesEnabled === true)
                this.templateCoordSets.push(coordSet);
        }

        this.templateCoordSets = this.templateCoordSets
            .sort((a, b) => a.name.localeCompare(b.name));

        this.context = this.canvasEditor.props.edgeTemplatePanelContext;
        this.canvasEditor.props.edgeTemplatePanelContextObservable
            .takeUntil(this.onDestroyEvent)
            .subscribe((context: PeekCanvasEdgeTemplatePropsContext) => {
                this.edgeTemplates = [];
                this.selectedEdgeTemplate = null;
                this.selectedCoordSetId = null;
                this.context = context;
                this.initSelectedCoordSetId();
            });
        this.initSelectedCoordSetId();
    }

    noedgeTemplates(): boolean {
        return this.edgeTemplates.length == 0;
    }

    isSelectedEdgeTemplate(item: DispEdgeTemplateT): boolean {
        return this.selectedEdgeTemplate != null && item.id == this.selectedEdgeTemplate.id;
    }

    selectedCoordSetIdChanged(coordSetId: number): void {
        this.selectedCoordSetId = coordSetId;

        let tupleSelector = new TupleSelector(GroupDispsTuple.tupleName, {
            "coordSetId": coordSetId
        });

        this.unsubSubject.next();

        this.tupleService.offlineObserver
            .subscribeToTupleSelector(tupleSelector)
            .takeUntil(this.unsubSubject)
            .takeUntil(this.onDestroyEvent)
            .subscribe((tuples: GroupDispsTuple[]) => {
                if (tuples.length == 0)
                    return;

                let gridDispTuple = tuples[0];

                if (gridDispTuple.encodedGridTuple == null)
                    return;

                Payload.fromEncodedPayload(gridDispTuple.encodedGridTuple)
                    .then((payload: Payload) => {
                        let gridTuple: GridTuple = payload.tuples[0];
                        let linkedGrid = new LinkedGrid(gridTuple, this.lookupService);
                        this.edgeTemplates = linkedGrid.disps
                            .sort((a, b) => DispGroup.groupName(a).localeCompare(DispGroup.groupName(b)));
                        this.initSelectedEdgeTemplate();
                    })
                    .catch((err) => {
                        console.log(`GridLoader.emitEncodedGridTuples decode error: ${err}`);
                    });
            });
    }

    dispName(disp: DispEdgeTemplateT): string {
        return DispEdgeTemplate.templateName(disp);
    }

    toggleEnabled(disp: DispEdgeTemplateT): void {
        this.selectedEdgeTemplate = disp;
        this.context.setEdgeTemplate(
            this.selectedEdgeTemplate, this.selectedCoordSetId
        );
    }


    private initSelectedCoordSetId(): void {
        if (this.context == null)
            return;

        let coordSetId = this.context.targetEdgeTemplateCoordSetId;

        if (coordSetId != null) {
            this.selectedCoordSetId = coordSetId;
            this.selectedCoordSetIdChanged(this.selectedCoordSetId);

        } else if (this.coordSet.editDefaultEdgeCoordSetId != null) {
            this.selectedCoordSetId = this.coordSet
                .editDefaultEdgeCoordSetId;
            this.selectedCoordSetIdChanged(this.selectedCoordSetId);

        } else if (this.templateCoordSets.length != 0) {
            this.selectedCoordSetId = this.templateCoordSets[0].id;
            this.selectedCoordSetIdChanged(this.selectedCoordSetId);

        }

    }


    private initSelectedEdgeTemplate(): void {
        if (this.context == null)
            return;

        let setName = (name) => {
            for (let edgeTemplate of this.edgeTemplates) {
                if (DispEdgeTemplate.templateName(edgeTemplate) == name) {
                    this.selectedEdgeTemplate = edgeTemplate;
                    break;
                }
            }
        };

        const name = this.context.targetEdgeTemplateName;

        if (name != null)
            setName(name);

        else if (this.coordSet.editDefaultEdgeGroupName != null)
            setName(this.coordSet.editDefaultEdgeGroupName);


    }


}
