import {
  action,
  observable,
  computed
} from 'mobx';
import { queryStringBuilder } from '../util/index';

export class BaseStore {
  
  url = '';
  mode = 'multi';
  
  @observable data = this.mode === 'multi' ? [] : {};
  // @observable data =  [] ;
  @observable selectedId = '';
  @observable selectedData = {};

  @observable isSearching = false;
  @observable dataFiltered = [];
  @observable searchResult = [];
  @observable isLoading = false;

  @observable currentPage = 1;
  @observable maxPage = 1;
  @observable dataPerPage = 30;

  @observable reqQuery = {};
  constructor(context) {
    this.context = context;
    this.http = context.http;
  }

  filterData = (query) => {
    return this.data.filter((data) => data.id.indexOf(query) > -1 || data.name.toLowerCase().indexOf(query.toLowerCase()) > -1 );
  }


  @action
  search(text){
    this.dataFiltered = this.filterData(text);
    console.log("dataFiltered" ,this.filterData(text));
  }

  @action 
  nextPage(reload=false) {
    if(this.currentPage == this.maxPage){
      return;
    }
    this.currentPage++;
    if (reload) {
      return this.getAll(true);
    }

    return Promise.resolve(true);
  };

  @action 
  prevPage(reload=false) {
    if(this.currentPage == 1){
      return;
    }
    this.currentPage--;

    if (reload) {
      return this.getAll();
    }

    return Promise.resolve(true);
  };

  @action
  async getAll(append=false) {
    this.isLoading = true;

    const q = queryStringBuilder(Object.assign({
      page: this.currentPage,
      per_page: this.dataPerPage,
    },this.reqQuery));

    const res = await this.http.get(`${this.url}?${q}`) 
      .catch(err => {
        this.isLoading = false;
        throw err;
      });

    this.maxPage = Math.ceil(res.max/this.dataPerPage);

    if (!append) {
      if(!res.data){
        this.data = res;
      }
      else{
        this.data = res.data;
      }
    } else {
      if(!res.data){
        this.data.replace(this.data.concat(res));
      }
      else{
        this.data.replace(this.data.concat(res.data));
      }
    }

    this.selectedData = {};
    this.selectedId = '';

    this.isLoading = false;
    return res;
  }

  @action
  async getDetail(id) {
    this.isLoading = true;
    const res = await this.http.get(`${this.url}/${id}`)
      .catch(err => {
        this.isLoading = false;
        throw err;
      });

    this.isLoading = false;
    this.setSelectedData(res);
    return res;
  }

  @action
  setSelectedData(data) {
    this.selectedData = data;
    this.selectedId = data.id;
  }

  @action
  create(data) {
    this.isLoading = true;
    return this.http.post(this.url, data)
      .then(res => {
        this.isLoading = false;
        this.getAll();
        return res;
      })
      .catch(err => {
        this.isLoading = false;
        throw err;
      })
  }

  @action
  update(id, data) {
    this.isLoading = true;
    return this.http.put(this.url + "/" + id, data)
      .then(res => {
        this.isLoading = false;
        this.getAll();
        return res;
      })
      .catch(err => {
        this.isLoading = false;
        throw err;
      })
  }

  @action
  delete(id) {
    this.isLoading = true;
    return this.http.delete(this.url + "/" + id)
      .then(res => {
        this.isLoading = false;
        return res;
      })
      .catch(err => {
        this.isLoading = false;
        throw err;
      });
  }

  @action
  setRequestQuery(q){
    //q is an object
    this.reqQuery = q;
  }

  @action
  reset(num=false){
    this.currentPage = 1;
    this.reqQuery = {};
  }

  @computed
  get isEmpty(){
    return this.data.length === 0;
  }
}
