import { Component, Input, Output, OnInit, EventEmitter, SimpleChanges, OnChanges, ViewChild } from '@angular/core';
import { Observable ,  of } from 'rxjs';
import { debounceTime,distinctUntilChanged,tap,switchMap,merge,catchError} from 'rxjs/operators';
import { TypeaheadService, TimespanService } from '@farmmaps/common';
import { IQueryState } from '@farmmaps/common';
import { IPeriodState } from '../../models/period.state';
import { tassign } from 'tassign';

@Component({
  selector: 'fm-map-map-search',
  templateUrl: './map-search.component.html',
  styleUrls: ['./map-search.component.scss']
})
export class MapSearchComponent {

  @ViewChild('searchText', { static: true }) searchText;
  @Input() clearEnabled: boolean
  @Input() set collapsed(collapsed: boolean) {
    this.collapsedLocal = collapsed;
    if (collapsed) this.searchText.nativeElement.blur();
  }
  @Input() set searchMinified(minified: boolean) {
    this.searchMinifiedLocal = minified;
  }
  @Input() period: IPeriodState
  @Output() onSearch = new EventEmitter<IQueryState>();
  @Output() onClear = new EventEmitter<any>();
  @Output() onSearchCollapse = new EventEmitter<any>();
  @Output() onSearchExpand = new EventEmitter<any>();
  @Output() onToggleMenu = new EventEmitter<any>();
  @Output() onOpenModal = new EventEmitter<string>();
  @Output() onCloseModal = new EventEmitter<any>();
  @Input() openedModalName: string;
  @Input() set filterOptions(filterOptions: IQueryState) {
    if (filterOptions && filterOptions.query && filterOptions.query.length > 0) {
      this.disabled = false;
    } else {
      this.disabled = true;
    }       
    this.filterOptionsLocal = tassign(this.filterOptionsLocal, { tags: filterOptions.tags, query: filterOptions.query,bbox:filterOptions.bbox });
    if (filterOptions.tags) {
      this.searchTextLocal = { name: filterOptions.tags };
    } else {
      this.searchTextLocal = { name: filterOptions.query };
    }
    if (this.dateFilter) {
      this.filterOptionsLocal.startDate = this.startDate;
      this.filterOptionsLocal.endDate = this.endDate;
    }
  }

  public collapsedLocal: boolean = true;
  public searchMinifiedLocal: boolean = false;
  public filterOptionsLocal: IQueryState;
  private extent: number[];
  public searchTextLocal: any;
  public searchTextLocalOutput: string; 
  public dateFilter: boolean = true;
  public startDate: Date = new Date(new Date(Date.now()).getFullYear(), new Date(Date.now()).getMonth() - 3, 1);
  public endDate: Date = new Date(Date.now());
  public startEndCaption: string = this.timespanService.getCaption(this.startDate, this.endDate, 4);

  searching = false;
  searchFailed = false;
  hideSearchingWhenUnsubscribed = new Observable(() => () => this.searching = false);

  public disabled: boolean = true;

  constructor(private typeaheadService: TypeaheadService, private timespanService: TimespanService) {
    this.filterOptionsLocal = { query: "", tags: "", startDate: null, endDate: null, bboxFilter: false, itemType: null, itemCode:null,level:0,parentCode:null,bbox:[] };   
  }

  search = (text$: Observable<string>) =>
    text$.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      tap(() => this.searching = true),
      switchMap(term => term.length < 1 ? of([]) :
        this.typeaheadService.getSearchTypeaheadItems(term).pipe(
          tap(() => this.searchFailed = false),
          catchError(() => {
            this.searchFailed = true;
            return of([]);
          })) ),
      tap(() => this.searching = false),
      merge(this.hideSearchingWhenUnsubscribed));

  formatter = (x: { name: string }) => x.name;

  handleSearch(event) {
    this.filterOptionsLocal.tags = null;
    this.filterOptionsLocal.itemType = null;
    this.filterOptionsLocal.itemCode = null;
    this.filterOptionsLocal.parentCode = null;
    this.filterOptionsLocal.query = this.searchTextLocalOutput;
    if (this.dateFilter) {
      this.filterOptionsLocal.startDate = this.startDate;
      this.filterOptionsLocal.endDate = this.endDate;
    }
    this.onSearch.emit(this.filterOptionsLocal);
  }

  handleOpenSelectPeriodModal(event: MouseEvent) {
    event.preventDefault();
    this.onOpenModal.emit('selectPeriodModal');
  }

  handleCloseModal() {
    this.onCloseModal.emit({});
  }

  handleSelect(event) {
    event.preventDefault();
    this.filterOptionsLocal.query = null;
    this.filterOptionsLocal.itemType = null;
    this.filterOptionsLocal.itemCode = null;
    this.filterOptionsLocal.parentCode = null;
    this.filterOptionsLocal.tags = event.item.name;
    if (this.dateFilter) {
      this.filterOptionsLocal.startDate = this.startDate;
      this.filterOptionsLocal.endDate = this.endDate;
    }
    this.onSearch.emit(this.filterOptionsLocal);
    this.searchTextLocal = { name: this.filterOptionsLocal.tags };
  }

  handleSelectPeriod(event: { startDate: Date, endDate: Date }) {
    this.startDate = event.startDate;
    this.endDate = event.endDate;   
    this.handleCloseModal();
    this.startEndCaption = this.timespanService.getCaption(event.startDate, event.endDate, 4);
    this.onSearch.emit(this.filterOptionsLocal);
  }

  handleChangeEnableDateFilter(enabled) {
    this.dateFilter = enabled;
    if (enabled) {
      this.filterOptionsLocal.startDate = this.startDate;
      this.filterOptionsLocal.endDate = this.endDate;
    } else {
      this.filterOptionsLocal.startDate = null;
      this.filterOptionsLocal.endDate = null;
    }
    if(this.filterOptionsLocal.query || this.filterOptionsLocal.tags)
      this.onSearch.emit(this.filterOptionsLocal);
  }

  handleChangeEnableBBOXFilter(enabled) {
    this.filterOptionsLocal.bboxFilter = enabled;
    if (this.filterOptionsLocal.query || this.filterOptionsLocal.tags)
      this.onSearch.emit(this.filterOptionsLocal);
  }


  handleToggleMenu(event) {
    this.onToggleMenu.emit({});
  }  

  handleFocus(event) {
    this.onSearchExpand.emit({});
  }

  handleChange(event: string) {
    this.searchTextLocalOutput = event;
    if (event && event.length == 1) {
      this.onSearchExpand.emit({});
    }
    if (event && event.length > 0)
      this.disabled = false;
    else
      this.disabled = true;
  }

  handleClearClick(event) {
    this.onClear.emit({});
  }
}