/*
 * 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 { BreakpointObserver } from '@angular/cdk/layout';
import { CdkOverlayOrigin, Overlay, OverlayConfig } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { Component, ComponentRef, HostBinding, Input, ViewChild, ViewContainerRef } from '@angular/core';

import { BOSCH_MEDIA_QUERIES } from '../../core-configuration/bosch-breakpoints';
import { BciSidebarService } from '../bci-sidebar/bci-sidebar.service';
import { ClosableOverlayComponentModel } from '../bci-sidebar/closable-overlay-component.model';
import { SidebarNavItem } from '../bci-sidebar/sidebar-nav-item.model';

/**
 * Time and timing curve for expansion panel animations.
 **/
export const SIDENAV_LINKS_ANIMATION_TIMING = '225ms cubic-bezier(0.4,0.0,0.2,1)';
export const ITEM_EXPANDED_STATES = { expanded: 'expanded', collapsed: 'collapsed' };

@Component({
  selector: 'bci-sidebar-nav-item',
  templateUrl: './bci-sidebar-nav-item.component.html',
  styleUrls: ['./bci-sidebar-nav-item.component.scss'],
  animations: [
    trigger('bodyExpansion', [
      state(ITEM_EXPANDED_STATES.collapsed, style({ height: '0px', visibility: 'hidden' })),
      state(ITEM_EXPANDED_STATES.expanded, style({ height: '*', visibility: 'visible' })),
      transition(
        `${ITEM_EXPANDED_STATES.expanded} <=> ${ITEM_EXPANDED_STATES.collapsed}`,
        animate(SIDENAV_LINKS_ANIMATION_TIMING)
      ),
    ]),
    trigger('indicatorRotate', [
      state(ITEM_EXPANDED_STATES.collapsed, style({ transform: 'rotate(90deg)' })),
      state(ITEM_EXPANDED_STATES.expanded, style({ transform: 'rotate(-90deg)' })),
      transition(
        `${ITEM_EXPANDED_STATES.expanded} <=> ${ITEM_EXPANDED_STATES.collapsed}`,
        animate(SIDENAV_LINKS_ANIMATION_TIMING)
      ),
    ]),
  ],
})
export class BciSidebarNavItemComponent {
  @Input() navItem: SidebarNavItem;
  @Input() showIcon = true;
  @Input() expandable = true;
  @Input() arrowRight = false;
  @Input() heading = false;
  @Input() secondLevel = false;
  @Input() tooltip = '';

  @ViewChild('popoverOrigin') popoverOrigin: CdkOverlayOrigin;

  @HostBinding('class.nav-link-hidden') get isHidden() {
    return !this.isSidebarOpen && !!this.navItem && !this.navItem.icon && !this.navItem.svgIcon;
  }

  get isSidebarOpen() {
    return this.sidebarService.isSidebarOpen;
  }

  constructor(
    public overlay: Overlay,
    public viewContainerRef: ViewContainerRef,
    private sidebarService: BciSidebarService,
    private breakpointObserver: BreakpointObserver
  ) {}

  hasLevel2Items() {
    return this.navItem.items && this.navItem.items.length > 0;
  }

  onFirstLevelClick() {
    if (this.hasLevel2Items() && this.expandable) {
      if (this.isSidebarOpen || !this.navItem.expanded) {
        this.navItem.expanded = !this.navItem.expanded;
      }
      this.sidebarService.setSidebarState(true);
    }
    if (this.hasLevel2Items() && !this.expandable) {
      this.sidebarService.setSidebarState(true);
      this.navItem.cb();
    } else if (this.navItem.cb) {
      this.navItem.cb();
    } else if ((this.navItem.url && !this.navItem.items) || (this.navItem.items && this.navItem.items.length === 0)) {
      if (this.breakpointObserver.isMatched(BOSCH_MEDIA_QUERIES.mobile)) {
        this.sidebarService.setSidebarState(false);
      }
      this.sidebarService.navigateToUrl(this.navItem.url, { queryParams: this.navItem.queryParams });
    } else if (this.navItem.overlay) {
      this.openOverlay();
    }
  }

  onSecondLevelClick(navItem: SidebarNavItem) {
    if (navItem.url) {
      if (this.breakpointObserver.isMatched(BOSCH_MEDIA_QUERIES.mobile)) {
        this.sidebarService.setSidebarState(false);
      }
      this.sidebarService.navigateToUrl(navItem.url, { queryParams: navItem.queryParams });
    } else if (navItem.cb) {
      navItem.cb();
    }
  }

  active(): boolean {
    if (!this.navItem.active) {
      return false;
    }
    if (!this.sidebarService.isSidebarOpen) {
      return true;
    }
    if (!this.hasLevel2Items()) {
      return true;
    }
    if (this.showIcon && !this.navItem.expanded) {
      return true;
    }
    if (!this.showIcon && this.navItem.expanded && !this.secondLevel) {
      return true;
    }
    if (!this.showIcon && !this.navItem.expanded && this.secondLevel) {
      return true;
    }
    return false;
  }

  activeAndExpandable(): boolean {
    return this.navItem.active && !this.secondLevel && !this.expandable;
  }

  expandedState(): string {
    return this.navItem.expanded && this.isSidebarOpen ? 'expanded' : 'collapsed';
  }

  openOverlay() {
    const strategy = this.overlay
      .position()
      .flexibleConnectedTo(this.popoverOrigin.elementRef)
      .withPositions([{ originX: 'end', originY: 'bottom', overlayX: 'start', overlayY: 'bottom' }]);

    const config = new OverlayConfig({
      positionStrategy: strategy,
      hasBackdrop: true,
      backdropClass: 'cdk-overlay-transparent-backdrop',
    });
    const overlayRef = this.overlay.create(config);

    const overlayComponent = this.navItem.overlay.component;
    const overlayConfig = this.navItem.overlay.config;

    const componentRef: ComponentRef<ClosableOverlayComponentModel<typeof overlayConfig>> = overlayRef.attach(
      new ComponentPortal(overlayComponent, this.viewContainerRef)
    );
    componentRef.instance.config = overlayConfig;
    componentRef.instance.onClose.subscribe(() => overlayRef.detach());
    overlayRef.backdropClick().subscribe(() => overlayRef.detach());
  }
}
