import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { CurrentGraphService } from '../../../services/current-graph.service';
import { from, of } from 'rxjs';
import { ConnectionViewRouterService } from '../../../services/connection-view-router.service';
import { Edge, Node } from '@swimlane/ngx-graph';
import { MatMenuTrigger } from '@angular/material/menu';
import { MatDialog } from '@angular/material/dialog';
import { EditConnectionDialogComponent } from '../../dialogs/edit-connection-dialog/edit-connection-dialog.component';
import { connection, newConnection } from '../../../types/connection';
import { filter, mergeMap, reduce, scan, switchMap, take, tap } from 'rxjs/operators';
import { ConfirmRemovalDialogComponent } from '../../dialogs/confirm-removal-dialog/confirm-removal-dialog.component';
import { node, nodeData } from '../../../types/node';
import { EditNodeDialogComponent } from '../../dialogs/edit-node-dialog/edit-node-dialog.component';
import { RemovalDialog } from '../../../types/ConfirmRemovalDialog';
import { CreateConnectionDialogComponent } from '../../dialogs/create-connection-dialog/create-connection-dialog.component';
import { CreateNewNodeDialogComponent } from '../../dialogs/create-new-node-dialog/create-new-node-dialog.component';

@Component({
  selector: 'osee-connectionview-graph',
  templateUrl: './graph.component.html',
  styleUrls: ['./graph.component.sass']
})
export class GraphComponent implements OnInit {

  @Input() editMode: boolean = false;
  data = this.graphService.nodes;
  update = this.graphService.updated;
  linkPosition = {
    x: "0",
    y:"0"
  }
  nodePosition = {
    x: "0",
    y:"0"
  }
  graphMenuPosition = {
    x: "0",
    y:"0"
  }
  @ViewChild('linkMenuTrigger') linkMenuTrigger!: MatMenuTrigger;
  @ViewChild('nodeMenuTrigger') nodeMenuTrigger!: MatMenuTrigger;
  @ViewChild('graphMenuTrigger') graphMenuTrigger!: MatMenuTrigger;
  constructor (private graphService: CurrentGraphService, private router: ConnectionViewRouterService, public dialog:MatDialog) {}

  ngOnInit(): void {
    this.graphService.update = true;
  }

  navigateToMessages(value: string) {
    this.router.connection = value;
  }

  navigateToMessagesInNewTab(location: string) {
    this.router.connectionInNewTab = location;
  }
  openLinkDialog(event:MouseEvent,value: Edge, nodes:Node[]) {
    event.preventDefault();
    this.linkPosition.x = event.clientX + 'px';
    this.linkPosition.y = event.clientY + 'px';
    //find node names based on value.data.source and value.data.target
    let source = nodes.find((node) => node.id === value.source);
    let target = nodes.find((node) => node.id === value.target);
    this.linkMenuTrigger.menuData = {
      data: value.data,
      source: source,
      target:target,
    }
    this.nodeMenuTrigger.closeMenu();
    this.graphMenuTrigger.closeMenu();
    this.linkMenuTrigger.openMenu();
  }

  /**
   * Opens Edit Dialog to Edit a connection, and sends response to Api
   * @param value connection to edit
   */
  openConnectionEditDialog(value: connection) {
    let dialogRef=this.dialog.open(EditConnectionDialogComponent, {
      data:Object.assign({},value)
    })
    dialogRef.afterClosed().pipe(
      //only take first response
      take(1),
      //filter out non-valid responses
      filter((dialogResponse) => dialogResponse !== undefined && dialogResponse !== null),
      //convert object to key-value pair emissions emitted sequentially instead of all at once
      mergeMap((arrayDialogResponse:connection) => from(Object.entries(arrayDialogResponse)).pipe(
        //filter out key-value pairs that are unchanged on value, and maintain id property
        filter((filteredProperties) => value[filteredProperties[0] as keyof connection] !== filteredProperties[1] || filteredProperties[0]==='id'),
        //accumulate into an array of properties that are changed
        reduce((acc, curr) => [...acc, curr], [] as [string, any][])
      )),
      //transform array of properties into Partial<connection> using Object.fromEntries()(ES2019)
      switchMap((arrayOfProperties) => of(Object.fromEntries(arrayOfProperties) as Partial<connection>).pipe(
        //HTTP PATCH call to update value
        switchMap((changes)=>this.graphService.updateConnection(changes))
      ))
    ).subscribe();
  }

  openRemoveConnectionDialog(value: connection, source:Node, target:Node) {
    let dialogRef = this.dialog.open(ConfirmRemovalDialogComponent, {
      data: {
        id: value.id,
        name: value.name,
        extraNames: [source.label,target.label],
        type:'connection'
      }
    })
    dialogRef.afterClosed().pipe(
      //only take first response
      take(1),
      //filter out non-valid responses
      filter((dialogResponse) => dialogResponse !== undefined && dialogResponse !== null),
      //make sure there is a name and id, and extra names
      filter((result) => result.name.length > 0 && result.id.length>0 && result.extraNames.length>0),
      mergeMap((dialogResults) => from([{ node:source.id,connection:dialogResults.id }, { node:target.id,connection:dialogResults.id }]).pipe(
        mergeMap((request)=>this.graphService.unrelateConnection(request.node,request.connection))
      ))
    ).subscribe();
  }

  openNodeDialog(event: MouseEvent, value: Node, edges:Edge[]) {
    event.preventDefault();
    this.nodePosition.x = event.clientX + 'px';
    this.nodePosition.y = event.clientY + 'px';
    let source = edges.filter((edge) => edge.source === value.id);
    let target = edges.filter((edge) => edge.target === value.id);
    this.nodeMenuTrigger.menuData = {
      data: value.data,
      sources: source,
      targets:target
    }
    this.linkMenuTrigger.closeMenu();
    this.graphMenuTrigger.closeMenu();
    this.nodeMenuTrigger.openMenu();
  }

  openEditNodeDialog(value: nodeData) {
    let dialogRef = this.dialog.open(EditNodeDialogComponent, {
      data:Object.assign({},value)
    })
    dialogRef.afterClosed().pipe(
      //only take first response
      take(1),
      //filter out non-valid responses
      filter((dialogResponse) => dialogResponse !== undefined && dialogResponse !== null),
      //convert object to key-value pair emissions emitted sequentially instead of all at once
      mergeMap((arrayDialogResponse:node) => from(Object.entries(arrayDialogResponse)).pipe(
        //filter out key-value pairs that are unchanged on value, and maintain id property
        filter((filteredProperties) => value[filteredProperties[0] as keyof node] !== filteredProperties[1] || filteredProperties[0]==='id'),
        //accumulate into an array of properties that are changed
        reduce((acc, curr) => [...acc, curr], [] as [string, any][])
      )),
      //transform array of properties into Partial<node> using Object.fromEntries()(ES2019)
      switchMap((arrayOfProperties) => of(Object.fromEntries(arrayOfProperties) as Partial<node>).pipe(
        //HTTP PATCH call to update value
        switchMap((results)=>this.graphService.updateNode(results))
      ))
    ).subscribe();
  }

  removeNodeAndConnection(value: nodeData,sources:Edge[],targets:Edge[]) {
    let dialogRef = this.dialog.open(ConfirmRemovalDialogComponent, {
      data: {
        id: value.id,
        name: value.name,
        extraNames: [...sources.map(x=>x.label),...targets.map(x=>x.label)],
        type:'node'
      }
    })
    dialogRef.afterClosed().pipe(
      //only take first response
      take(1),
      //filter out non-valid responses
      filter((dialogResponse:RemovalDialog) => dialogResponse !== undefined && dialogResponse !== null),
      //make sure there is a name and id
      filter((result) => result.name.length > 0 && result.id.length > 0),
      //delete Node api call, then unrelate connection from other node(s) using unrelate api call
      switchMap((results)=>this.graphService.deleteNodeAndUnrelate(results.id,[...sources,...targets])) //needs testing
    ).subscribe();
  }

  createConnectionToNode(value: nodeData) {
    //todo open dialog to select node to connect to this node
    let dialogRef = this.dialog.open(CreateConnectionDialogComponent, {
      data:value
    })
    dialogRef.afterClosed().pipe(
      //only take first response
      take(1),
      //filter out non-valid responses
      filter((dialogResponse: newConnection) => dialogResponse !== undefined && dialogResponse !== null),
      //HTTP Rest call to create connection(branch/nodes/nodeId/connections/type), then rest call to relate it to the associated nodes(branch/nodes/nodeId/connections/id/type)
      switchMap((results)=>this.graphService.createNewConnection(results.connection,results.nodeId,value.id))
    ).subscribe();
  }

  openGraphDialog(event: MouseEvent) {
    event.stopPropagation();
    event.preventDefault();
    //hacky way of keeping the event to white space only instead of activating on right mouse click of other elements
    let target = event.target as HTMLElement
    if (target.attributes.getNamedItem('class')?.value == 'panning-rect') {
      this.graphMenuPosition.x = event.clientX + 'px';
      this.graphMenuPosition.y = event.clientY + 'px';
      this.linkMenuTrigger.closeMenu();
      this.nodeMenuTrigger.closeMenu();
      this.graphMenuTrigger.openMenu();
    }
  }

  createNewNode() {
    let dialogRef = this.dialog.open(CreateNewNodeDialogComponent);
    dialogRef.afterClosed().pipe(
      take(1),
      filter((dialogResponse: node) => dialogResponse !== undefined && dialogResponse !== null),
      switchMap((results)=>this.graphService.createNewNode(results))
    ).subscribe()
  }
}
