const $ = require('jquery');
const Bloodhound = require("typeahead.js/dist/bloodhound.js");
const Typeahead = require("typeahead.js/dist/typeahead.jquery.js");
const Cookies = require('js-cookie');

class IhkSwitch {
  constructor(section) {
    const t = this;
    this.serviceUrlBase = "/blueprint/servlet/serviceport/ihkfinder";
    this.ihklListUrl = 'services/ihkList.json';//this.serviceUrlBase + "/ihk/all";
    this.communitiesUrl = 'services/communities.json';//this.serviceUrlBase + "/community/all";

    // berechnen d
    // center ist geolocation aus js api
    // item die IHK
    /*
    const p = 0.017453292519943295;
    const c = Math.cos;
    const a = 0.5 - c((item.lat - center.lat) * p) / 2 + c(center.lat * p) * c(item.lat * p) * (1 - c((item.lng - center.lng) * p)) / 2;
    const distance = 12742 * Math.asin(Math.sqrt(a));
    */

    $(section).addClass("initialized");
    t.section = section;
    t.form = section.find('.ihk-finder');
    t.charMap = {
      'a': /[àáâ]/gi,
      'c': /[ç]/gi,
      'e': /[èéêë]/gi,
      'i': /[ï]/gi,
      'o': /[ô]/gi,
      'oe': /[œ]/gi,
      'u': /[ü]/gi,
      's': /[ß]/gi
    };

    t.initClosing();
    t.checkState();
  }

  initClosing() {
    this.section.find('.closer').on('click', () => {
      this.section.addClass('hide');
      setTimeout(() => {
        this.section.removeAttr('data-show-step');
      }, 400);
    })
  }

  checkState() {
    const cookie = Cookies.get('my-ihk');

    if (cookie) {
      this.initSwitch();
    } else {
      this.initGeolocation();
    }
  }

  loadIhkList(callback) {
    $.getJSON(this.ihklListUrl, (response) => {
      if (response.jsonResponse && response.status === 200) {
        this.ihkList = response.jsonResponse.sort((a, b) => {
          const countryNameA = a.country.toUpperCase(); // ignore upper and lowercase
          const countryNameB = b.country.toUpperCase(); // ignore upper and lowercase
          // Sort by country
          if (countryNameA < countryNameB) {
            return -1;
          }
          if (countryNameA > countryNameB) {
            return 1;
          }
          const ihkNameA = a.name.toUpperCase(); // ignore upper and lowercase
          const ihkNameB = b.name.toUpperCase(); // ignore upper and lowercase
          // Sort by name
          if (ihkNameA < ihkNameB) {
            return -1;
          }
          if (ihkNameA > ihkNameB) {
            return 1;
          }
          // names must be equal
          return 0;
        });
        //console.log(this.ihkList);
        callback();
      }
    })
  }

  loadCommunities(callback) {
    $.getJSON(this.communitiesUrl, (communities) => {
      if (communities.jsonResponse && communities.status === 200) {
        this.communities = communities.jsonResponse;
        callback();
      }
    });
  }

  initForm() {
    this.section.attr('data-show-step', 'form');

    if (this.communities && this.ihkList) {
      this.initBloodhound(this.communities);
    }
    else {
      this.loadIhkList(() => { this.loadCommunities( () => { this.initBloodhound(this.communities) } ) });
    }
    this.form.on('submit', function () {
      /*
      if ($('.tt-cursor').length) {
        $('.tt-cursor').trigger('click');
      } else if ($('.tt-suggestion').length > 1) {
        $('.tt-suggestion').first().trigger('click');
      }
      */
      return false;
    });
  }

  initGeolocation() {
    navigator.geolocation.getCurrentPosition((pos) => {this.locationSuccess(pos)}, (err) => {this.locationError(err)});
    this.section.find('.change-location').on('click', () => {
      this.initForm();
    })
    this.section.find('.accept-location').on('click', () => {
      this.setCookie();
    })
    this.section.find('.toggle-location-info').on('click', (e) => {
      e.preventDefault();
      this.section.find('#location-info').slideToggle(250, 'swing');
    })
  }

  setCookie() {
    const myIHK = this.ihkList.find(ihk => {
      return ihk.ihknr === this.myLocation.ihk
    })
    delete myIHK.zips;
    Cookies.set('my-ihk', JSON.stringify(myIHK).toString(), { expires: 365 });
    this.initSwitch();
  }

  locationSuccess(position) {
    let url = 'https://api.bigdatacloud.net/data/reverse-geocode-client?localityLanguage=de';
    url += '&latitude=' + position.coords.latitude;
    url += '&longitude=' + position.coords.longitude;

    $.getJSON(url, (location) => {
      this.section.find('.my-location').text(location.postcode + ' ' + location.city);
      this.myLocation = {
        city: location.city,
        zip: location.postcode
      }
      this.loadCommunities(() => {this.checkMyLocation()});
    })
  }

  checkMyLocation() {
    this.myLocation.ihk = -1;
    $.each(this.communities, (index, value) => {
      if (this.normalize(this.myLocation.city).toUpperCase() === value.name || (value.zips && value.zips.indexOf(this.myLocation.zip) > -1)) {
        this.myLocation.ihk = value.ihknr;
        this.loadIhkList(() => {this.completeGeolocation()});
        return false;
      }
    });

    if (this.myLocation.ihk === -1) {
      this.initForm();
    }
  }

  completeGeolocation() {
    const myIHK = this.ihkList.find(ihk => {
      return ihk.ihknr === this.myLocation.ihk
    })
    if (myIHK) {
      this.section.find('.my-ihk').text('IHK ' + myIHK.name);
      this.section.attr('data-show-step', 'geolocation');
    }
    else {
      this.initForm();
    }
  }

  locationError(error) {
    this.section.attr('data-show-step', 'form');
    this.initForm();
  }

  initBloodhound(data) {
    const t = this;
    $.each(data, function (index, value) {
      data[index]['normName'] = t.normalize(data[index].name);
    });
    data.sort(function (a, b) {
      if (a.name < b.name) return -1;
      if (a.name > b.name) return 1;
      return 0;
    });
    t.communities = new Bloodhound({
      datumTokenizer: function (d) {
        var titleTokens = Bloodhound.tokenizers.whitespace(d.normName);
        return titleTokens.concat(d.zips)
      },
      queryTokenizer: function (q) {
        var normalized = t.normalize(q);
        return Bloodhound.tokenizers.whitespace(normalized);
      },
      local: data,
      limit: 50
    });
    t.communities.initialize();
    var src = {
      name: 'communities',
      displayKey: 'name',
      source: t.communities.ttAdapter(),
      templates: {
        empty: ['<p class="no-result">Leider nichts gefunden</p>'].join('\n'),
        suggestion: function (e) {
          return ('<div data-id="' + e.ihknr + '" ><span class="name">' + e.name + '</span/><span class="zip">' + (e.zips ? e.zips.join(', ') : ' ') + '</span></div>');
        }
      }
    }
    t.initTypeahead(src);
  }

  initTypeahead(source) {
    const t = this;
    const input = t.form.find('input[type="text"]');
    input.typeahead({
        highlight: true,
        ttl_ms: 0
      },
      source
    );
    input.bind('typeahead:selected', (e, item) => {
      if (!this.myLocation) {
        this.myLocation = {}
      }
      this.myLocation.city = item.name;
      this.myLocation.ihk = item.ihknr;
      this.initSwitch();
    });
  }

  initSwitch() {
    let myIHK;
    const currIHK = parseInt(this.section.find('.current-ihk').attr('data-ihknr'));
    if (this.myLocation && this.myLocation.ihk) {
      myIHK = this.ihkList.find(ihk => {
        return ihk.ihknr === this.myLocation.ihk
      })
    }
    else {
      myIHK = JSON.parse(Cookies.get('my-ihk'));
    }
    if (currIHK !== myIHK.ihknr) {
      this.section.find('.my-ihk').text('IHK ' + myIHK.name);
      this.section.attr('data-show-step', 'switch');
    }

    this.section.find('.stay-here').on('click', () => {
      this.section.find('.closer').trigger('click');
    })
    this.section.find('.change-ihk').on('click', () => {
      this.initSuccess();
    })
  }

  initSuccess() {
    this.section.attr('data-show-step', 'success');
    console.log('add redirect link!');
  }

  navigateTo(link) {
    //console.log('SET COOKIE: ' + link.attr('data-ihknr'));
    window.location = link.attr('href');
  }

  normalize(str) {
    const t = this;
    $.each(t.charMap, function (normalized, regex) {
      str = str.replace(regex, normalized);
    });
    return str;
  }
}

$(document).ready(function () {
  $('.ihk-switch:not(.initialized)').each(function (i) {
    new IhkSwitch($(this));
  });
});
