/*
 * Copyright (C) 2018 Robert Bosch GmbH Copyright (C) 2018 Robert Bosch Manufacturing Solutions GmbH, Germany. All rights reserved.
 */

import { animate, state, style, transition, trigger } from '@angular/animations';
import { Component, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { ResolveStart, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { BciSidebarService } from '../bci-sidebar/bci-sidebar.service';
import { SidebarNavItem } from '../bci-sidebar/sidebar-nav-item.model';

const animationTransition = 'true <=> false';
const animation = '225ms cubic-bezier(0.4,0.0,0.2,1)';

@Component({
  selector: 'bci-sidebar-nav-list',
  templateUrl: './bci-sidebar-nav-list.component.html',
  styleUrls: ['./bci-sidebar-nav-list.component.scss'],
  animations: [
    trigger('leftTighten', [
      state('true', style({ width: '55px' })),
      state('false', style({ width: '*' })),
      transition(animationTransition, animate(animation)),
    ]),
    trigger('rightExpansion', [
      state('false', style({ width: '0px' })),
      state('true', style({ width: '*' })),
      transition(animationTransition, animate(animation)),
    ]),
  ],
})
export class BciSidebarNavListComponent implements OnInit, OnChanges {
  @Input() navItems: SidebarNavItem[] = [];
  /**
   * @todo enable skipSorting to be set (SidebarService? Configuration?)
   */
  skipSorting = false;
  url = '/';

  constructor(private router: Router, private sidebarService: BciSidebarService) {}

  ngOnInit() {
    this.setURL();
    this.setNavItemActive(this.navItems);
    this.setNavItemExpanded(this.navItems);

    this.router.events.subscribe((e) => {
      if (e instanceof ResolveStart) {
        this.setURL(e.url);
        this.setNavItemActive(this.navItems);
      }
    });
  }

  ngOnChanges(changes: SimpleChanges): void {
    if (!this.skipSorting && changes.navItems) {
      this.navItems.sort((a, b) => a.position - b.position);
      this.setNavItemActive(this.navItems);
    }
  }

  has3Levels(): boolean {
    return (
      this.navItems
        .filter((item) => item.items)
        .map((items) => items.items)
        .filter((itemArray) => itemArray.filter((item) => item.items && item.items.length > 0).length > 0).length > 0
    );
  }

  hasNavItems(navItem): boolean {
    if (!navItem.items) {
      return false;
    }
    return navItem.items.length > 0;
  }

  parentNavItems(): SidebarNavItem[] {
    return this.navItems.map((item) => {
      if (item.items && item.items.length > 0) {
        item.cb = () => (this.url = item.url);
      }
      return item;
    });
  }

  subNavItems(): SidebarNavItem[] {
    const navItem = this.activeMainNavItem();
    if (!navItem) {
      return [];
    }
    return navItem.items || [];
  }

  tooltip(navItem): Observable<string> {
    return this.sidebarService.getSidebarState().pipe(
      map((sidebarState) => {
        if (!sidebarState || (this.has3Levels() && this.subNavItems().length > 0)) {
          return navItem.title;
        }
        return '';
      })
    );
  }

  expanded(): string {
    return (this.has3Levels() && this.subNavItems().length > 0).toString();
  }

  parentNavItem(): SidebarNavItem {
    const parentItem = new SidebarNavItem();
    parentItem.title = this.activeMainNavItem().title;
    parentItem.cb = () => {
      this.setURL('/');
      this.collapseNavItems(this.activeMainNavItem().items);
      if (this.activeMainNavItem()) {
        this.activeMainNavItem().expanded = false;
      }
    };
    parentItem.routerLinkActiveOptions = { exact: true };
    return parentItem;
  }

  private setURL(route?: string) {
    let url = route || this.router.url;

    if (url.indexOf('?') >= 0) {
      url = url.substring(0, url.indexOf('?'));
    }

    if (url !== '/') {
      url = url.substr(1);
    }

    this.url = url;
  }

  private setNavItemActive(items: Array<SidebarNavItem>) {
    if (!items) {
      return;
    }
    items.forEach((item) => {
      item.active = this.hasActiveChild(item);
      this.setNavItemActive(item.items);
    });
  }

  private setNavItemExpanded(items: Array<SidebarNavItem>) {
    if (!items) {
      return;
    }
    items.forEach((item) => {
      item.expanded = this.hasActiveChild(item);
      this.setNavItemExpanded(item.items);
    });
  }

  private collapseNavItems(items: Array<SidebarNavItem>) {
    if (!items) {
      return;
    }
    items.forEach((item) => {
      item.active = false;
      item.expanded = false;
      this.collapseNavItems(item.items);
    });
  }

  private hasActiveChild(item: SidebarNavItem): boolean {
    if (item.items) {
      const activeItems = item.items.filter((subItem) => !!this.hasActiveChild(subItem));
      if (activeItems.length > 0) {
        return true;
      }
    }

    if (item.routerLinkActiveOptions && item.routerLinkActiveOptions.exact) {
      return item.url === this.url;
    }

    return ('/' + this.url).indexOf(item.url) !== -1;
  }

  private activeMainNavItem(): SidebarNavItem {
    const activeLink = this.url.split('/')[0] || this.url.split('/')[1];
    const navItem = this.navItems.filter((item) => item.url.indexOf(activeLink) !== -1)[0];

    if (!navItem) {
      return this.navItems.filter((item) => item.expanded && item.active)[0];
    }

    return navItem;
  }

  private closeUnselectedNavItems(items: Array<SidebarNavItem>) {
    if (!items) {
      return;
    }
    items.forEach((item) => {
      item.expanded = item.active;
      this.closeUnselectedNavItems(item.items);
    });
  }
}
