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

import {
  AfterViewInit,
  ChangeDetectorRef,
  Component,
  ContentChildren,
  forwardRef,
  HostBinding,
  OnDestroy,
  QueryList,
} from '@angular/core';
import { merge, of, Subject } from 'rxjs';
import { delay, takeUntil } from 'rxjs/operators';
import { CommandbarItemComponent } from '../item/commandbar-item.component';

@Component({
  selector: 'bci-commandbar-quickfilters',
  templateUrl: './commandbar-quickfilters.component.html',
  styleUrls: ['./commandbar-quickfilters.component.scss'],
})
export class CommandbarQuickfiltersComponent implements OnDestroy, AfterViewInit {
  @HostBinding('class.commandbar-group')
  @HostBinding('class.commandbar-group-quickfilters')
  true;

  @ContentChildren(forwardRef(() => CommandbarItemComponent)) items: QueryList<CommandbarItemComponent>;
  public visibleItems: CommandbarItemComponent[] = [];
  public hiddenItems: CommandbarItemComponent[] = [];

  private componentDestroyed$ = new Subject<void>();
  private width: number;
  private firstRender = true;
  private readonly minWidth = 1;
  private readonly maxWidth = 90;

  constructor(private cdr: ChangeDetectorRef) {}

  ngOnDestroy() {
    this.componentDestroyed$.next();
    this.componentDestroyed$.complete();
  }

  ngAfterViewInit() {
    // listen to items changes
    merge(of(true), this.items.changes)
      .pipe(
        delay(0), // avoid change after checked exceptions
        takeUntil(this.componentDestroyed$) // takeUntil has to be ordered after delay
      )
      .subscribe(() => {
        this.updateChanges();
      });
  }

  public updateView(width?: number) {
    if (width !== undefined) {
      this.width = width;
    }

    if (!this.items) {
      return;
    }

    if (this.firstRender) {
      this.visibleItems = [...this.items.toArray()];
      this.hiddenItems = [];
      this.firstRender = false;
    }

    if (this.width < this.minWidth && this.visibleItems.length > 0) {
      this.hiddenItems.unshift(this.visibleItems.pop());
    } else if (this.width > this.maxWidth && this.hiddenItems.length) {
      this.visibleItems.push(this.hiddenItems.shift());
    }

    this.cdr.detectChanges();
  }

  public hasHiddenItems() {
    return !!this.hiddenItems.length;
  }

  public hasVisibleItems() {
    return !!this.visibleItems.length;
  }

  private updateChanges() {
    const itemsArray = this.items.toArray();
    if (!this.visibleItems.length && this.hiddenItems.length) {
      this.hiddenItems = [...itemsArray];
      this.visibleItems = [];
    } else {
      this.visibleItems = [...itemsArray];
      this.hiddenItems = [];
    }
    this.updateView();
  }
}
