import { Component, OnDestroy, OnInit } from '@angular/core';
import { ConfigService } from '@shared/config/config.service';
import { MenuModel } from '../../models/menu.model';
import { AuthService } from '@shared/auth/auth.service';
import { MenuItemContainerModel } from '../../models/menu-item-container.model';
import { OrderingService } from '@shared/ui-api/ordering.service';
import { DynamicUiApiService } from '@fleio-api/dynamic-ui/dynamic-ui-api.service';
import { MenuItemModel } from '../../models/menu-item.model';
import { FilteringService } from '@shared/ui-api/filtering.service';
import { NavigationEnd, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { MenuService } from '@shared/ui/menu/menu.service';

@Component({
  selector: 'app-side-nav-menu',
  templateUrl: './side-nav-menu.component.html',
  styleUrls: ['./side-nav-menu.component.scss']
})
export class SideNavMenuComponent implements OnInit, OnDestroy {
  menu = {items: []} as MenuModel;
  activeClientLink: MenuItemModel = null;
  activeClientChanged: boolean;
  private routerSubscription: Subscription;
  private observableMenuItemsCountSubscription = null

  constructor(
    private config: ConfigService,
    private router: Router,
    public authService: AuthService,
    private orderingService: OrderingService,
    private filteringService: FilteringService,
    private dynamicUiApiService: DynamicUiApiService,
    private menuService: MenuService,
  ) {
  }

  public canShowMenuItemContainer(menuItemContainer: MenuItemContainerModel) {
    let itemsNotShownCount = 0;
    for (const item of menuItemContainer.items) {
      if (typeof item === 'boolean' && item === false) {
        itemsNotShownCount += 1;
      }
    }
    return menuItemContainer.items.length !== itemsNotShownCount;
  }

  initActiveClientLink() {
    const activeClient = this.authService.activeClient();
    if (activeClient) {
      this.activeClientLink = {
        type: 'menuItem', // menuItem
        route: 'clients',
        href: null,
        angular_route: 'clients',
        label: activeClient.long_name,
        icon: null,
        icon_class: 'fl-icons',
        queryParams: this.orderingService.getQueryParams('clients'),
        feature: 'clients&users.switch-client',
        open_in_new_tab: false,
        ellipse: true,
        activeClientItem: true,
        activeClient,
      };
    }
  }

  ngOnInit() {
    this.initActiveClientLink();
    this.config.activeClientChanged$.subscribe(value => {
      if (value) {
        if (this.activeClientLink) {
          const newActiveClient = this.authService.activeClient(value);
          this.activeClientLink.label = newActiveClient.long_name;
          this.activeClientLink.activeClient = newActiveClient;
        } else {
          this.initActiveClientLink();
        }
        this.activeClientChanged = true;
      }
    });
    this.authService.loggedInCompleted.subscribe(() => {
      this.loadMenu();
    });
    this.orderingService.ordering$.subscribe(() => {
      if (this.menu && this.menu.items && this.menu.items.length) {
        this.refreshMenuItemsQueryParams();
      }
    });
    this.filteringService.filteringChange$.subscribe(() => {
      if (this.menu && this.menu.items && this.menu.items.length) {
        this.refreshMenuItemsQueryParams();
      }
    });

    this.routerSubscription = this.router.events.subscribe(event => {
      if (event instanceof NavigationEnd) {
        if (this.activeClientChanged) {
          // if active client changed refresh menu since it may be different
          // due to role permissions or override features
          this.activeClientChanged = false;
          this.loadMenu();
        }
      }
    });

    this.observableMenuItemsCountSubscription = this.menuService.observableMenuItemsCount.subscribe(value => {
      if (value) {
        this.loadMenu();
      }
    });
  }

  private refreshMenuItemsQueryParams() {
    for (let menuEntry of this.menu.items) {
      if (menuEntry.type === 'menuItem') {
        menuEntry = this.setMenuEntryParams(menuEntry);
      } else if (menuEntry.type === 'menuItemContainer') {
        for (let menuItemEntry of menuEntry.items) {
          menuItemEntry = this.setMenuEntryParams(menuItemEntry);
        }
      }
    }
    if (this.activeClientLink) {
      this.setMenuEntryParams(this.activeClientLink);
    }
  }

  private setMenuEntryParams(menuEntry: MenuItemModel): any {
    if (menuEntry.angular_route !== null) {
      if (menuEntry.angular_route === '') {
        menuEntry.route = this.config.getPanelHomeUrl();
        menuEntry.queryParams = {};
      } else {
        menuEntry.route = this.config.getPanelUrl(menuEntry.angular_route);
        menuEntry.queryParams = this.orderingService.getQueryParams(menuEntry.angular_route);
        menuEntry.queryParams = this.filteringService.updateQueryParams(menuEntry.angular_route, menuEntry.queryParams);
      }
    }
    return menuEntry;
  }

  private loadMenu() {
    if (this.authService.userData && this.authService.userData.user) {
      this.dynamicUiApiService.getAppMenu().subscribe(response => {
        this.menu.items = response.menu;
        this.refreshMenuItemsQueryParams();
      });
    }
  }

  ngOnDestroy() {
    if (this.routerSubscription) {
      this.routerSubscription.unsubscribe();
      this.routerSubscription = null;
    }
    if (this.observableMenuItemsCountSubscription) {
      this.observableMenuItemsCountSubscription.unsubscribe();
      this.observableMenuItemsCountSubscription = null;
    }
  }
}
