import { Component, ViewContainerRef, forwardRef, AfterViewInit, Input, OnInit } from '@angular/core';
import { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';

export const SELECT_CONTROL_VALUE_ACCESSOR: any = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: forwardRef(() => SelectComponent),
  multi: true
};

@Component({
  selector: 'ui-kit-select',
  templateUrl: './select.component.html',
  styleUrls: ['../../../styles/css/select.css'],
  providers: [SELECT_CONTROL_VALUE_ACCESSOR]
})
export class SelectComponent implements OnInit {
  @Input() label: string = '';
  @Input() class: string = '';
  @Input() opened: boolean = false;
  @Input() placeholder: string;
  @Input() options: any[] = [];
  @Input() active: boolean;

  private el: Element;
  private internalValue: any;

  private onTouchedCallback: () => void = () => { };
  private onChangeCallback: (_: any) => void = () => { };

  constructor(viewContainerRef: ViewContainerRef) {
    this.el = viewContainerRef.element.nativeElement;
  }

  get value(): any {
    return this.internalValue;
  };

  set value(value: any) {
    if (value !== this.internalValue) {
      let data = this.options.filter(o => o.value === value).pop();
      this.internalValue = data.title;
      this.onChangeCallback(value);
    }
  }

  ngOnInit() {
    this.class = `ui-kit-select-container ${this.class}`;

    let body = document.querySelector('body');

    body.addEventListener('click', e => {
      if (!this.opened || !e.target) { return; };
      if (this.el !== e.target && !this.el.contains((<any>e.target))) {
        this.close();
      }
    }, false);
  }

  select(i: number) {
    this.options = this.options.map((o, ii) => {
      if (ii === i) {
        o.selected = true;
        this.value = o.value;
      } else {
        o.selected = false;
      }
      return o;
    });

    this.close();
  }

  toggle() {
    this.opened = !this.opened;
  }

  close() { this.opened = false; }

  open() { this.opened = true; }

  writeValue(value: any) {
    if (value !== this.internalValue) {
      setTimeout(() => {
        let data = this.options.filter(o => o.value === value).pop();
        if (data) {
          this.internalValue = data.title;
        }
      });
    }
  }

  onBlur() {
    this.onTouchedCallback();
  }

  registerOnChange(fn: any) {
    this.onChangeCallback = fn;
  }

  registerOnTouched(fn: any) {
    this.onTouchedCallback = fn;
  }
}
