import appDialogsManager from "../lib/appManagers/appDialogsManager";
import Scrollable from "./scrollable";
import appMessagesManager from "../lib/appManagers/appMessagesManager";
import InputSearch from "./inputSearch";

export class SearchGroup {
  container: HTMLDivElement;
  nameEl: HTMLDivElement;
  list: HTMLUListElement;

  constructor(public name: string, public type: string, private clearable = true, className?: string, clickable = true, public autonomous = true, public onFound?: () => void) {
    this.list = appDialogsManager.createChatList();
    this.container = document.createElement('div');
    if(className) this.container.className = className;
    
    if(name) {
      this.nameEl = document.createElement('div');
      this.nameEl.classList.add('search-group__name');
      this.nameEl.innerText = name;
      this.container.append(this.nameEl);
    }
    
    this.container.classList.add('search-group', 'search-group-' + type);
    this.container.append(this.list);
    this.container.style.display = 'none';

    if(clickable) {
      appDialogsManager.setListClickListener(this.list, onFound, undefined, autonomous);
    }
  }

  clear() {
    this.container.style.display = 'none';

    if(this.clearable) {
      this.list.innerHTML = '';
    }
  }

  setActive() {
    this.container.style.display = '';
  }

  toggle() {
    if(this.list.childElementCount) {
      this.setActive();
    } else {
      this.clear();
    }
  }
}

export type SearchGroupType = 'contacts' | 'globalContacts' | 'messages' | string;

export default class AppSearch {
  private minMsgId = 0;
  private loadedCount = -1;
  private foundCount = -1;

  private searchPromise: Promise<void> = null;
  private searchTimeout: number = 0;

  private query = '';

  public listsContainer: HTMLDivElement = null;

  private peerId = 0; // 0 - means global
  private threadId = 0;

  private scrollable: Scrollable;

  constructor(public container: HTMLElement, public searchInput: InputSearch, public searchGroups: {[group in SearchGroupType]: SearchGroup}, public onSearch?: (count: number) => void) {
    this.scrollable = new Scrollable(this.container);
    this.listsContainer = this.scrollable.container as HTMLDivElement;
    for(let i in this.searchGroups) {
      this.listsContainer.append(this.searchGroups[i as SearchGroupType].container);
    }

    if(this.searchGroups.messages) {
      this.scrollable.setVirtualContainer(this.searchGroups.messages.list);
    }

    this.searchInput.onChange = (value) => {
      /* if(!value.trim()) {
        //this.peerId = 0;
        return;
      } */
      
      this.query = value;
      this.reset(false);
      this.searchMore();
    };

    this.scrollable.onScrolledBottom = () => {
      if(!this.query.trim()) return;
    
      if(!this.searchTimeout) {
        this.searchTimeout = window.setTimeout(() => {
          this.searchMore();
          this.searchTimeout = 0;
        }, 0);
      }
    };
  }

  public reset(all = true) {
    if(all) {
      this.searchInput.value = '';
      this.query = '';
      this.peerId = 0;
      this.threadId = 0;
    }

    this.minMsgId = 0;
    this.loadedCount = -1;
    this.foundCount = -1;

    for(let i in this.searchGroups) {
      this.searchGroups[i as SearchGroupType].clear();
    }
    
    this.searchPromise = null;
  }

  public beginSearch(peerId?: number, threadId?: number) {
    if(peerId) {
      this.peerId = peerId;
    }

    if(threadId) {
      this.threadId = threadId;
    }
    
    this.searchInput.input.focus();
  }

  public searchMore() {
    if(this.searchPromise) return this.searchPromise;
    
    const query = this.query;
    
    if(!query.trim()) {
      this.onSearch && this.onSearch(0);
      return;
    }
    
    if(this.foundCount !== -1 && this.loadedCount >= this.foundCount) {
      return Promise.resolve();
    }
    
    const maxId = this.minMsgId || 0;

    return this.searchPromise = appMessagesManager.getSearch({
      peerId: this.peerId, 
      query, 
      inputFilter: {_: 'inputMessagesFilterEmpty'}, 
      maxId, 
      limit: 20,
      threadId: this.threadId
    }).then(res => {
      this.searchPromise = null;
      
      if(this.searchInput.value !== query) {
        return;
      }
      
      //console.log('input search result:', this.peerId, query, null, maxId, 20, res);
      
      const {count, history} = res;
      
      if(history.length && history[0].mid === this.minMsgId) {
        history.shift();
      }
      
      const searchGroup = this.searchGroups.messages;

      history.forEach((message) => {
        const {dialog, dom} = appDialogsManager.addDialogNew({
          dialog: message.peerId, 
          container: this.scrollable/* searchGroup.list */, 
          drawStatus: false,
          avatarSize: 54
        });
        appDialogsManager.setLastMessage(dialog, message, dom, query);
      });

      searchGroup.toggle();
      
      this.minMsgId = history.length && history[history.length - 1].mid;
      
      if(this.loadedCount === -1) {
        this.loadedCount = 0;
      }
      this.loadedCount += history.length;
      
      if(this.foundCount === -1) {
        this.foundCount = count;
        this.onSearch && this.onSearch(this.foundCount);
      }
    }).catch(err => {
      console.error('search error', err);
      this.searchPromise = null;
    });
  }
}
