/********************************************************************************
 * Copyright (c) 2015, 2023 Contributors to the Eclipse Foundation
 *
 * See the NOTICE file(s) distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 ********************************************************************************/

import { DatePipe } from "@angular/common";
import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute } from "@angular/router";
import { TRANSLATE } from "@core/mdm-core.module";
import { MDMItem } from "@core/mdm-item";
import { MDMNotificationService } from "@core/mdm-notification.service";
import { SystemParameterService } from "@details/services/systemparameter.service";
import { FileLinkContextWrapper } from "@file-explorer/model/file-explorer.model";
import { ContextFilesService } from "@file-explorer/services/context-files.service";
import { FileService } from "@file-explorer/services/file.service";
import { NavigatorService } from "@navigator/navigator.service";
import { Attribute, ContextGroup, Node } from "@navigator/node";
import { TranslateService } from "@ngx-translate/core";
import { TreeNode } from "primeng/api";
import { TreeTable } from "primeng/treetable";
import { of, Subscription } from "rxjs";
import { catchError, finalize, skip, take, tap } from "rxjs/operators";
import { Role } from "src/app/authentication/authentication.service";
import { EntityCreatorService } from "src/app/entity-creator/entity-creator.service";
import { MDMEntity } from "src/app/entity-creator/model/mdm-entity";
import { TimezoneService } from "src/app/timezone/timezone-service";
import { AuthenticationService } from "../../../authentication/authentication.service";
import { Components, Context, ContextAttributeIdentifier, Sensor } from "../../model/details.model";
import { ContextService } from "../../services/context.service";

@Component({
  selector: "mdm-detail-context",
  templateUrl: "mdm-detail-descriptive-data.component.html",
  styleUrls: ["mdm-detail-descriptive-data.component.css"],
})
export class MDMDescriptiveDataComponent implements OnInit, OnDestroy {
  private readonly StatusLoading = TRANSLATE("details.mdm-detail-descriptive-data.status-loading");
  private readonly StatusSaving = TRANSLATE("details.mdm-detail-descriptive-data.status-saving");
  private readonly StatusNoNodes = TRANSLATE("details.mdm-detail-descriptive-data.status-no-nodes-available");
  private readonly StatusVirtualNodes = TRANSLATE("details.mdm-detail-descriptive-data.status-virtual-node-selected");
  private readonly StatusNoDescriptiveData = TRANSLATE("details.mdm-detail-descriptive-data.status-no-descriptive-data-available");

  public treeNodes: { [key: string]: TreeNode[] };

  // this holds the type dependant original context data in case of cancelling the edit mode
  private tmpTreeNodes: Node[];

  public selectedNode: Node;
  public contextType: string;

  public contextComponents: Components;
  public sensors: Sensor[];
  public status: string;

  // reference to be able to use enum in html template
  public contextGroupEnum = ContextGroup;

  public editMode: boolean;

  public isTreeTableExpanded = true;

  private sub = new Subscription();

  public tplComponents: MDMEntity[];
  public selectedTplComponent: MDMEntity[] = [];
  public showTplComponents = false;
  public selectedContext: string[] = [];
  public showConfirmDelete = false;
  public selectedContextComponentName: string;
  ctxCompName = { ctxName: "" };
  hasOrdered: boolean;
  hasMeasured: boolean;

  constructor(
    private route: ActivatedRoute,
    private _contextService: ContextService,
    private navigatorService: NavigatorService,
    private notificationService: MDMNotificationService,
    private translateService: TranslateService,
    private datePipe: DatePipe,
    private authenticationService: AuthenticationService,
    private fileService: FileService,
    private contextFileService: ContextFilesService,
    private systemParameterService: SystemParameterService,
    private entityCreatorService: EntityCreatorService,
    private timezoneService: TimezoneService,
  ) {}

  public canEdit: boolean;
  public isTest: boolean;

  public canEdit4Env: boolean;
  private editAllowed: { [key: string]: boolean } = {};

  ngOnInit() {
    this.authenticationService.isUserInRole([Role.Admin.toString(), Role.User.toString()]).subscribe((b) => (this.canEdit = b));
    this.status = this.StatusNoNodes;
    this.editMode = false;

    this.timezoneService.timezoneChanged.subscribe(() => {
      this.reloadData();
    });

    this.sub.add(
      this.route.params.subscribe(
        (params) => this.refreshContextData(params["context"]),
        (error) =>
          this.notificationService.notifyError(
            this.translateService.instant("details.mdm-detail-descriptive-data.err-cannot-load-scope"),
            error,
          ),
      ),
    );
    // node changed from the navigation tree
    this.sub.add(
      this.navigatorService
        .onSelectionChanged()
        .pipe(
          skip(1), // skip first to avoid double loading, since path param also changes for sure on init.
          tap((obj) => this.handleSelectionChanged(obj)),
          finalize(() => (this.status = this.StatusNoDescriptiveData)),
          catchError((error) =>
            of(
              this.notificationService.notifyError(
                this.translateService.instant("details.mdm-detail-descriptive-data.err-cannot-load-data"),
                error,
              ),
            ),
          ),
        )
        .subscribe(),
    );

    // file changed
    this.fileService.onFileChanged().subscribe((link) => this.handleFileChanged(link));
  }

  ngOnDestroy() {
    this.sub.unsubscribe();
  }

  private handleSelectionChanged(obj: Node | MDMItem) {
    this.isTest = false;
    if (obj instanceof MDMItem) {
      this.selectedNode = undefined;
      this.status = this.StatusVirtualNodes;
    } else {
      this.refreshDetailData(obj);
      this.handleEditMode(obj);
    }
  }

  handleFileChanged(fileLinkContextWrapper: FileLinkContextWrapper) {
    if (this.treeNodes != undefined) {
      this.treeNodes[fileLinkContextWrapper.contextType]
        .filter((tnode) => tnode.label === fileLinkContextWrapper.contextComponent.name)
        .map((tnode) => tnode.children)
        .reduce((a, b) => a.concat(b), [])
        .filter((tnode) => tnode.data.attribute.name === fileLinkContextWrapper.attribute.name)
        .forEach((tnode) => (tnode.data.attribute = fileLinkContextWrapper.attribute));
      // spread is necessary for treeTable changeDetection
      this.treeNodes[fileLinkContextWrapper.contextType] = [...this.treeNodes[fileLinkContextWrapper.contextType]];
    }
  }

  setContext(context: string) {
    switch (context) {
      case "uut":
        this.contextType = "UNITUNDERTEST";
        break;
      case "te":
        this.contextType = "TESTEQUIPMENT";
        break;
      case "ts":
        this.contextType = "TESTSEQUENCE";
        break;
    }
  }

  /**
   * Listener method to change the context tab
   *
   * @param contextType
   */
  refreshContextData(contextType: string) {
    // revert before changing the context
    this.reloadData();
    this.setContext(contextType);
    this.editMode = false;
  }

  private reloadData() {
    this.sub.add(
      this.navigatorService
        .onSelectionChanged()
        .pipe(
          take(1),
          tap((object) => this.handleSelectionChanged(object)),
        )
        .subscribe(),
    );
  }

  /**
   * Listener method to change the node
   *
   * @param node
   */
  refreshDetailData(node: Node) {
    this.status = this.StatusLoading;
    if (node != undefined) {
      this.selectedNode = node;
      this.editMode = false;
      this.contextComponents = undefined;
      this.treeNodes = undefined;
      if (node.type.toLowerCase() === "measurement" || node.type.toLowerCase() === "teststep" || node.type.toLowerCase() === "test") {
        this.loadContext(node);
      } else {
        this.status = this.StatusNoDescriptiveData;
      }
      if (node.type.toLowerCase() === "test") {
        this.isTest = true;
      }
    }
  }

  /**
   * Load the context data for the provided node
   *
   * @param node
   */
  private loadContext(node: Node) {
    this._contextService.getContext(node).subscribe((components) => this.setComponents(components));
  }

  getContextAttribute(
    contextDescribable: Node,
    contextComponent: Node,
    attribute: Attribute,
    contextGroup?: ContextGroup,
    contextType?: string,
  ) {
    return new ContextAttributeIdentifier(contextDescribable, contextComponent, attribute, contextGroup, contextType);
  }

  getNodeClass(item: Node) {
    return "icon " + item.type.toLowerCase();
  }

  /**
   * Change the tree state to expanded or collapsed
   *
   * @param type
   * @param expand
   */
  toggleTreeNodeState(tt: TreeTable) {
    this.isTreeTableExpanded = !this.isTreeTableExpanded;
    const nodeArray = this.treeNodes[this.contextType];
    if (nodeArray != undefined) {
      for (const node of nodeArray) {
        this.recursiveChangeNodes(node, this.isTreeTableExpanded);
      }
    }

    // invoke table update when pressing the plus or minus buttons from the table header
    tt.updateSerializedValue();
    tt.tableService.onUIUpdate(tt.value);
  }

  /**
   * Change the tree node state recursively
   *
   * @param node
   * @param expand
   */
  recursiveChangeNodes(node: TreeNode, expand: boolean) {
    node.expanded = expand;
    if (node.children != undefined && node.children.length > 0) {
      for (const child of node.children) {
        this.recursiveChangeNodes(child, expand);
      }
    }
  }

  /**
   * Get the nodes from the current context
   *
   * @param nodes
   * @param parentId optional parent id which will get the child nodes
   */
  getNodes(nodes: Node[], parentId: string) {
    return nodes.filter((n) => this.nodeIsInCurrentContext(n, parentId));
  }

  nodeIsInCurrentContext(node: Node, parentId: string) {
    const parentNodeId = node.relations != null && node.relations.length > 0 ? node.relations[0].parentId : null;
    return (parentId === null && parentNodeId === null) || (parentId != null && parentNodeId != null && parentId === parentNodeId);
  }

  /**
   * Create a tree node based on the mdm entity
   *
   * @param node
   * @param context
   */
  createTreeNode(node: Node, children: Node[], contextType: string) {
    const data = {
      name: node.name,
      // 'attribute': node,
      header: true,
      mimeType: this.extractMimeType(node),
      optional: node.optional,
      id: node.id,
    };
    return <TreeNode>{
      label: node.name,
      data: data,
      children: this.createTreeChildren(node, children, data, contextType),
      icon: this.getNodeClass(node),
      expanded: true,
      optional: node.optional,
      defaultActive: node.defaultActive,
      testStepSeriesVariable: node.testStepSeriesVariable,
    };
  }

  /**
   * Create the tree children nodes recursive based on the mdm attributes and subsequent mdm entities
   *
   * @param node the current node
   * @param contexts the complete contexts
   */
  createTreeChildren(node: Node, children: Node[], parentData: any, contextType: string) {
    const list = node.attributes
      .filter((attr) => attr.name !== "MimeType" && attr.name !== "Name" && attr.name !== "Sortindex")
      .map((attribute) => {
        const patchedAttribute = this.patchAttribute(node, attribute, contextType);
        return {
          data: {
            name: attribute.name,
            attribute: patchedAttribute,
            header: false,
            mimeType: this.extractMimeType(node),
            orderedContextAttribute: this.getContextAttribute(
              parentData,
              this.selectedNode,
              patchedAttribute,
              ContextGroup.ORDERED,
              contextType,
            ),
            measuredContextAttribute: this.getContextAttribute(
              parentData,
              this.selectedNode,
              patchedAttribute,
              ContextGroup.MEASURED,
              contextType,
            ),
          },
          expanded: true,
        } as TreeNode;
      });

    const tplCompRel = node.relations.find((r) => r.entityType === "TemplateComponent");
    if (tplCompRel && tplCompRel.ids.length > 0) {
      const nodes = this.getNodesWithTplCompId(children, tplCompRel.ids[0]);
      for (const n of nodes) {
        list.push(this.createTreeNode(n, children, contextType));
      }
    }

    return list;
  }

  /**
   * Searches for nodes which have a relation to the given TemplateComponent ID.
   * @param nodes List with nodes to search
   * @param tplCompId  TemplateComponent ID
   */
  getNodesWithTplCompId(nodes: Node[], tplCompId: string) {
    return nodes.filter((n) => n.relations[0].parentId === tplCompId);
  }

  private extractMimeType(node: Node) {
    if (node != undefined) {
      const attr = node.attributes.find((attr) => attr.name === "MimeType");
      if (attr) {
        if (typeof attr.value === "string") {
          return attr.value;
        } else if (Array.isArray(attr.value) && attr.value.length === 1 && typeof attr.value[0] === "string") {
          return attr.value[0];
        } else if (Array.isArray(attr.value) && attr.value.length > 1 && typeof attr.value[1] === "string") {
          return attr.value[1];
        }
      }
    }
  }

  /**
   * Method to create a tree structure from the flat context entity and attribute map
   *
   * @param components
   */
  mapComponents(components: Components) {
    const list: { [key: string]: TreeNode[] } = {};
    if (components != undefined) {
      for (const key of Object.keys(components)) {
        const nodes: Node[] = this.getNodes(components[key], null);
        if (nodes != undefined) {
          list[key] = nodes.map((node) => this.createTreeNode(node, components[key], key));
        }
      }
    }
    return list;
  }

  /**
   * Convert, complement or load attribute values
   *
   * @param attribute
   */
  patchAttribute(node: Node, attribute: Attribute, contextType: string) {
    if (attribute.dataType != null && attribute.dataType.length > 0) {
      const val = attribute.value as any[];
      if ("FILE_RELATION" === attribute.dataType) {
        if (val.length > 0) {
          this.contextFileService
            .getMDMFileExts(this.getContextAttribute(node, this.selectedNode, attribute, ContextGroup.ORDERED, contextType))
            .subscribe((mdmLinks) => (val[0] = mdmLinks));
        }
        if (val.length > 1) {
          this.contextFileService
            .getMDMFileExts(this.getContextAttribute(node, this.selectedNode, attribute, ContextGroup.MEASURED, contextType))
            .subscribe((mdmLinks) => (val[1] = mdmLinks));
        }
      }
    }

    return attribute;
  }

  /** *********************
   * Edit functions start
   ********************** */

  convertFixedDateStr(dt: string, convertForUI: boolean) {
    let newDt = dt;
    let sourceFormat = "";

    /**
     * Get the translation immediately
     */
    sourceFormat = this.translateService.instant("details.mdm-detail-descriptive-data.transform-dateformat");

    if (dt != null && dt.length > 0 && convertForUI && dt.indexOf("T") > -1) {
      // for display purpose
      const tmpDt = this.parseISOString(dt);
      newDt = this.datePipe.transform(tmpDt, sourceFormat, "+0000");
    } else if (dt != null && dt.length > 0 && !convertForUI && dt.indexOf("T") === -1) {
      // re-convert UI date to server date for persistence
      if (newDt.indexOf("-") === -1) {
        // find the date patterns dd, MM and yyyy and grab the according index positions
        const startDay = sourceFormat.indexOf("d");
        const endDay = sourceFormat.lastIndexOf("d");
        const startMonth = sourceFormat.indexOf("M");
        const endMonth = sourceFormat.lastIndexOf("M");
        const startYear = sourceFormat.indexOf("y");
        const endYear = sourceFormat.lastIndexOf("y");
        // manually attach the time as toISOString() will not properly transform the winter/summer time
        newDt =
          dt.substring(startYear, endYear + 1) + "-" + dt.substring(startMonth, endMonth + 1) + "-" + dt.substring(startDay, endDay + 1);
        if (dt.indexOf(" ") > -1) {
          // use the provided timestamp
          newDt = newDt + "T" + dt.substring(dt.indexOf(" ") + 1) + ":00Z";
        } else {
          newDt = newDt + "T00:00:00Z";
        }
        if (newDt.length !== 20) {
          newDt = "";
        }
      }
    }
    return newDt;
  }

  /**
   * Fixed parsing for ISO date string
   *
   * @param s
   */
  parseISOString(s: string) {
    const b: any[] = s.split(/\D+/);
    return new Date(Date.UTC(b[0], --b[1], b[2], b[3], b[4], b[5], b[6]));
  }

  /**
   * Send the changed data to the backend
   *
   * @param node
   * @param type
   */
  private putContext(node: Node, type: string) {
    if (type === null) {
      return;
    }
    this.status = this.StatusSaving;
    this.treeNodes = undefined;

    const data = new Context();
    data.ordered = new Components();
    data.ordered[type] = this.getNodesWithUpdatedContent(this.contextComponents[type] as Node[], true);

    data.measured = new Components();
    data.measured[type] = this.getNodesWithUpdatedContent(this.contextComponents[type] as Node[], false);

    if (data.ordered[type].length === 0 && data.measured[type].length === 0) {
      this.treeNodes = this.mapComponents(this.contextComponents);
      return;
    }

    // clear for status display
    this.contextComponents = undefined;

    this._contextService.putContext(node, data).subscribe(
      (components) => {
        this.setComponents(components);
      },
      (error) =>
        this.notificationService.notifyError(
          this.translateService.instant("details.mdm-detail-descriptive-data.err-cannot-load-context"),
          error,
        ),
    );
  }

  onEdit(event: Event) {
    event.stopPropagation();
    this.editMode = true;
    this.tmpTreeNodes = JSON.parse(JSON.stringify(this.contextComponents[this.contextType]));
  }

  onCancelEdit(event: Event) {
    event.stopPropagation();
    this.editMode = false;
    this.isTreeTableExpanded = true;
    this.reloadData();
  }

  onSaveChanges(event: Event) {
    event.stopPropagation();
    this.editMode = false;
    this.isTreeTableExpanded = true;
    this.putContext(this.selectedNode, this.contextType);
    this.tmpTreeNodes = undefined;
  }

  onAddTempComponent(event: Event) {
    event.stopPropagation();
    this.entityCreatorService.getTemplateTestStep(this.selectedNode).subscribe((r) => {
      if (r.length > 0 && r[0].relations.filter((rel) => rel.contextType === this.contextType).length > 0) {
        this.entityCreatorService.getTemplateComponents(r[0], this.contextType).subscribe((co) => {
          this.setTplComponents(co);
          this.showTplComponents = true;
        });
      } else {
        this.notificationService.notifyInfo(
          this.translateService.instant("details.mdm-detail-descriptive-data.info-no-tempComp"),
          this.translateService.instant("details.mdm-detail-descriptive-data.msg-no_tplComp"),
        );
      }
    });
  }

  setTplComponents(entities: MDMEntity[]) {
    if (entities !== undefined) {
      let cIds: string[] = [];
      this.contextComponents[this.contextType].forEach((attr) => {
        if (attr.attributes[0].value.length === 2 && attr.attributes[0].value[0] !== undefined) {
          attr.relations.forEach((rel) => {
            if (rel.contextType === this.contextType) {
              cIds = cIds.concat(rel.ids);
            }
          });
        }
      });
      this.tplComponents = [];
      entities
        .filter(
          (ent) =>
            cIds.filter((id) => id === ent.id)[0] === undefined &&
            ent.attributes.filter((attr) => attr.name === "Optional" && attr.value === "true"),
        )
        .forEach((entity) => this.tplComponents.push(entity));
    }
  }

  onSaveSelection(event: Event) {
    event.stopPropagation();
    const compNames: string[] = [];
    this.selectedTplComponent.forEach((ent) => compNames.push(ent.name));
    this._contextService
      .addNewComponent(this.selectedNode.sourceName, this.contextType, this.selectedNode.id, compNames, this.selectedContext)
      .subscribe((components) => this.setComponents(components));
    this.selectedTplComponent = [];
    this.showTplComponents = false;
  }

  onDeleteComponent(event: Event, name: string) {
    event.stopPropagation();
    this.hasOrdered = this.contextComponents[this.contextType].filter((cmp) => cmp.name === name)[0].attributes[0].value[0] !== undefined;
    this.hasMeasured = this.contextComponents[this.contextType].filter((cmp) => cmp.name === name)[0].attributes[0].value.length === 2;
    this.selectedContext = [];
    this.selectedContextComponentName = name;
    this.ctxCompName = { ctxName: name };
    this.showConfirmDelete = true;
  }

  onNotDeleteSelection(event: Event) {
    event.stopPropagation();
    this.showConfirmDelete = false;
  }

  onDeleteSelection(event: Event) {
    if (this.selectedContext?.length > 0) {
      event.stopPropagation();
      this._contextService
        .deleteComponent(
          this.selectedNode.sourceName,
          this.contextType,
          this.selectedNode.id,
          this.selectedContextComponentName,
          this.selectedContext,
        )
        .subscribe((components) => this.loadContext(this.selectedNode));
      this.showConfirmDelete = false;
    }
  }

  private setComponents(components: Components) {
    if (components["UNITUNDERTEST"] != undefined || components["TESTEQUIPMENT"] != undefined || components["TESTSEQUENCE"] != undefined) {
      this.contextComponents = components;
      this.treeNodes = this.mapComponents(components);
    } else {
      this.status = this.StatusNoDescriptiveData;
    }
  }
  /**
   * Get the updated nodes from the current context
   *
   * @param contextComponents
   * @param type the context type
   * @param ordered true if ordered data, false if measured data
   */
  getNodesWithUpdatedContent(contextComponents: Node[], ordered: boolean) {
    const list = [];
    for (const component of contextComponents) {
      const attrs = [];
      for (const cAttribute of component.attributes) {
        const attr = new Attribute();
        let addAttr = true;
        attr.dataType = cAttribute.dataType;
        attr.name = cAttribute.name;
        attr.unit = cAttribute.unit;
        attr.value = "";

        if (ordered && cAttribute.value instanceof Array && cAttribute.value.length > 0) {
          attr.value = cAttribute.value[0];
        } else if (!ordered && cAttribute.value instanceof Array && cAttribute.value.length > 1) {
          attr.value = cAttribute.value[1];
        }
        // lookup new value from treenodes
        if (attr.dataType === "BOOLEAN" && attr.value != null && attr.value.toString().length > 0) {
          attr.value = attr.value.toString() === "true" ? "1" : "0";
        }

        // FILE_LINK_SEQUENCE is saved separately
        if (attr.dataType === "FILE_LINK_SEQUENCE" || attr.dataType === "FILE_LINK" || attr.dataType === "FILE_RELATION") {
          addAttr = false;
        }

        if (addAttr) {
          if (this.isAttributeValueModified(attr, component, ordered)) {
            attrs.push(attr);
          }
        }
      }
      // un-merged list
      if (attrs.length > 0) {
        const c = JSON.parse(JSON.stringify(component));
        c.attributes = attrs;
        list.push(c);
      }
    }
    return list;
  }

  private isAttributeValueModified(attr: Attribute, component: Node, ordered: boolean) {
    for (const tmpNode of this.tmpTreeNodes) {
      if (tmpNode.name === component.name) {
        for (const attribute of tmpNode.attributes) {
          if (attribute.name === attr.name && attribute.value instanceof Array) {
            const orgValue = ordered ? attribute.value[0] : attribute.value.length > 1 ? attribute.value[1] : undefined;
            if (orgValue != undefined) {
              if (attr.dataType === "BOOLEAN") {
                // server value = true or false, UI value = 1 or 0
                return (
                  (attr.value === "0" && orgValue === "true") ||
                  (attr.value === "1" && orgValue === "false") ||
                  (attr.value !== "" && orgValue === "")
                );
              } else {
                // plain comparison
                return attr.value !== orgValue;
              }
            }
            return false;
          }
        }
      }
    }
  }

  /** *********************
   * Edit functions end
   ********************** */

  handleEditMode(node: Node) {
    if (node != undefined) {
      if (this.editAllowed[node.sourceName] != undefined) {
        this.canEdit4Env = this.canEdit && this.editAllowed[node.sourceName];
      } else {
        this.systemParameterService.findSystemParameter(node.sourceName, "org.eclipse.mdm.detailview.editable").subscribe((values) => {
          if (values.length === 1) {
            this.editAllowed[node.sourceName] = values[0].attributes.find((attr) => attr.name === "Value").value === "false" ? false : true;
          } else {
            this.editAllowed[node.sourceName] = true;
          }
          this.canEdit4Env = this.canEdit && this.editAllowed[node.sourceName];
        });
      }
    }
  }
}
