import { Component, OnInit, ElementRef, EventEmitter, Input, Output, HostListener } from '@angular/core';
import { NotificationService } from '../../services/notification.service';
import { BannerMessageStatusEn, ErrorType } from '../../common/enums';
import { MessageService, MessageDefines } from '../../services/message.service';

@Component({
  selector: 'app-autocomplete',
  templateUrl: './autocomplete.component.html',
  styleUrls: ['./autocomplete.component.css']
})
export class AutocompleteComponent {

  @Input() responsibilityForwarding = '';
  @Output() responsibilityForwardingChange = new EventEmitter();
  inputElementList: string[] = [];
  filteredList: any[] = [];
  item: any;
  items: any[] = [];
  elementRef;
  alreadyFocused = false;
  position: number = -1;

  constructor(autoCompleteElement: ElementRef,
    private messageService: MessageService,
    private notificationService: NotificationService) {
    this.elementRef = autoCompleteElement;
  }

  searchChanged(newValue) {
    if (newValue === '') {
      newValue = null;
    }
    this.responsibilityForwarding = newValue;
    this.responsibilityForwardingChange.emit(newValue);
  }

  setAssignedUserSuggestions() {
    this.notificationService.getAssignedUserSuggestions().subscribe(res => {
      this.inputElementList = res;
      this.createItemList();
    },
      error => { 
        this.messageService.emitError('Benutzervoschlag', ErrorType.retrieve); 
      }
    );
  }

  filterQuery() {
    this.filteredList = this.items.filter((el: any) => {
      if (this.responsibilityForwarding == null) {
        return el.name.toLowerCase().indexOf(this.responsibilityForwarding) > -1;
      } else {
        return el.name.toLowerCase().indexOf(this.responsibilityForwarding.toLowerCase()) > -1;
      }
    });
  }

  filter(event: any) {

    if (this.responsibilityForwarding !== '') {
      if ((event.keyCode >= 48 && event.keyCode <= 57) ||
        (event.keyCode >= 65 && event.keyCode <= 90) ||
        (event.keyCode === 8)) {

        this.position = -1;
        this.filterQuery();

      }
    } else {
      this.filteredList = [];
    }

    for (let i = 0; i < this.filteredList.length; i++) {
      this.filteredList[i].selected = false;
    }

    // Arrow-key Down
    if (event.keyCode === 40) {
      if (this.position + 1 !== this.filteredList.length) {
        this.position++;
      }
    }

    // Arrow-key Up
    if (event.keyCode === 38) {
      if (this.position > 0) {
        this.position--;
      }
    }

    if (this.filteredList[this.position] !== undefined) {
      this.filteredList[this.position].selected = true;
    }

    //enter
    if (event.keyCode === 13) {
      if (this.filteredList[this.position] !== undefined) {
        this.select(this.filteredList[this.position]);
      }
    }

    // Handle scroll positionition of item
    const suggestionsGroup = document.getElementById('suggestions-id');
    const listItem = document.getElementById('true');
    if (listItem) {
      suggestionsGroup.scrollTop = (listItem.offsetTop - 100);
    }

  }

  select(item: any) {
    this.filteredList = [];
    this.position = -1;
    if (item.name === '') {
      item.name = null;
    }
    this.responsibilityForwarding = item.name;
    this.responsibilityForwardingChange.emit(item.name);
  }

  @HostListener('keydown', ['$event'])
  handleKeyDown(event: any) {
    // Prevent default actions of arrows
    if (event.keyCode === 40 || event.keyCode === 38) {
      event.preventDefault();
    }
  }

  handleFocus() {
    if (!this.alreadyFocused) {
      this.setAssignedUserSuggestions();
      this.alreadyFocused = true;
    }
  }

  createItemList() {
    this.inputElementList.forEach(element => {
      this.items.push({
        name: element,
        selected: false
      });
    });
  }

  @HostListener('document:click', ['$event'])
  handleClick(event) {
    let clickedComponent = event.target;
    let inside = false;
    do {
      if (clickedComponent === this.elementRef.nativeElement) {
        inside = true;
      }
      clickedComponent = clickedComponent.parentNode;
    } while (clickedComponent);
    if (!inside) {
      this.filteredList = [];
    }
    this.position = -1;
  }

  @HostListener('document:keypress', ['$event'])
  handleKeyboardEvent(event: any) {
    let clickedComponent = event.target;
    let inside = false;
    do {
      if (clickedComponent === this.elementRef.nativeElement) {
        inside = true;
      }
      clickedComponent = clickedComponent.parentNode;
    } while (clickedComponent);

    if (inside) {
      if (event.keyCode === 13) {
        if (this.filteredList[this.position] !== undefined) {
          this.select(this.filteredList[this.position]);
        }
        //stops the key event to be propagated        
        event.preventDefault();
      }
    }
  }

}
