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

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

@Component({
  selector: 'bci-commandbar-actions',
  templateUrl: './actions.component.html',
  styleUrls: ['./actions.component.scss'],
})
export class CommandbarActionsComponent implements OnDestroy, AfterViewInit {
  @ContentChildren(forwardRef(() => CommandbarItemComponent)) items: QueryList<CommandbarItemComponent>;

  public visibleItems: CommandbarItemComponent[] = [];
  public hiddenItems: CommandbarItemComponent[] = [];

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

  constructor(public intl: BciSharedIntl, private cdr: ChangeDetectorRef) {}

  get renderLargeInlinedItemVariants(): boolean {
    return this._renderLargeInlinedItemVariants;
  }

  /**
   * Whether to show labels in commandbar and more-actions menu.
   */
  @Input() set renderLargeInlinedItemVariants(value: boolean) {
    this._renderLargeInlinedItemVariants = value;
    this.updateChanges();
  }

  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;
    }

    this.visibleItems.forEach((item) => {
      // show/hide item content
      item.renderLargeVariant = this.renderLargeInlinedItemVariants;

      // flag the item as action button if item is an instance of CommandbarButtonComponent
      if (item instanceof CommandbarButtonComponent) {
        (item as CommandbarButtonComponent).isCommandbarActionButton = true;
      }
    });

    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() {
    if (!this.items) {
      return;
    }
    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();
  }
}
