/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80*/
/*global window, RSVP, rJS, document, DOMParser, URL*/
(function (window, RSVP, rJS, document, DOMParser, URL) {
  "use strict";
  var gadget_klass = rJS(window);

  gadget_klass

  .setState({
    body_list: []
  })
  .declareAcquiredMethod("getUrlFor", "getUrlFor")

  .declareMethod("showResultBox", function () {
    var box = document.getElementById("results");

    if (box.classList.contains("hide")) {
      box.classList.remove("hide");
    }
  })
  .declareMethod("hideResultBox", function () {
    var box = document.getElementById("results");

    if (!box.classList.contains("hide")) {
      box.classList.add("hide");
    }
  })

  .declareMethod("startLoading", function () {
    var loader;

    loader = document.getElementById("mynij-loading");
    loader.style.display = "block";
    loader = document.getElementById("searx-loading");
    loader.style.display = "block";
    return this.changeState({body_list: []});
  })

  .declareMethod("addItem", function (item, key) {
    var list,
        list_item,
        title,
        link,
        link_par,
        body_list = [],
        gadget = this;

    list = document.getElementById("mynij-results");
    list_item = document.createElement("li");
    list_item.id = Math.random().toString(36) + '-' + Date.now();
    if (item.link.startsWith("?url=")) {
      item.link = item.link.substring(5);
    }

    return gadget.cut_link(item.link)
      .push(function (cut_link) {
        title = document.createElement("a");
        title.appendChild(document.createTextNode(item.title));
        title.className = "title";
        title.href = item.link;
        list_item.appendChild(title);
        link = document.createElement("a");
        link.appendChild(document.createTextNode(cut_link));
        link.href = item.link;
        link.className = "link";
        link_par = document.createElement('p');
        link_par.appendChild(link);
        list_item.appendChild(link_par);
      })
      .push(function () {
        var loader = document.getElementById("mynij-loading");

        loader.style.display = "none";
        if (key === "" || item.content === "") {
          list.appendChild(list_item);
        } else {
          list.appendChild(list_item);
          gadget.state.body_list.push({
            element: list_item,
            content: item.content,
            key: key
          });
        }
      });
  })

  .declareService(function () {
    var gadget = this,
        delay = 10,
        item;

    function add_description() {
      if (!gadget.state.body_list.length) {
        return new RSVP.Queue()
          .push(function () {
            return RSVP.delay(1000);
          })
          .push(function () {
            return add_description();
          });
      }

      item = gadget.state.body_list.shift();
      return gadget.cut_description(item.content, item.key)
        .push(function (description) {
          var body,
              regex = new RegExp(item.key, "ig"),
              match_list,
              key_map = {};
          match_list = description.match(regex);
          if (match_list) {
            match_list.forEach(function (value) {
              key_map[value] = '<b>' + value + '</b>';
            });
            regex = new RegExp(Object.keys(key_map).join("|"), "gi");
            description = description.replace(regex, function (matched) {
              return key_map[matched];
            });
          }
          body = document.createElement('p');
          body.className = "body";
          body.innerHTML = description;
          item.element.appendChild(body);
        })
        .push(function () {
          return RSVP.delay(delay);
        })
        .push(function () {
          return add_description();
        });
    }
    return add_description();
  })

  .declareMethod("add_searx_no_result", function (msg) {
    var error_html,
        list_item = document.createElement("li"),
        loader = document.getElementById("searx-loading"),
        list = document.getElementById("searx-results");

    loader.style.display = "none";
    error_html = document.createElement("p");
    error_html.className = "no-result";
    error_html.textContent = msg;
    list_item.appendChild(error_html);
    list.appendChild(list_item);
  })

  .declareMethod("show_searx_result", function (item, key) {
    var list,
        list_item,
        title,
        link,
        link_par,
        body,
        loader = document.getElementById(
          "searx-loading");

    loader.style.display = "none";
    list = document.getElementById("searx-results");
    list_item = document.createElement("li");

    title = document.createElement("a");
    title.appendChild(document.createTextNode(
      item.querySelector('h4.result_header').textContent));
    title.className = "title";
    title.href = item.querySelector('div.external-link').textContent;
    list_item.appendChild(title);

    link = document.createElement("a");
    link.appendChild(document.createTextNode(
      item.querySelector('div.external-link').textContent));
    link.href = item.querySelector('div.external-link').textContent;
    link.className = "link";
    link_par = document.createElement("p");
    link_par.appendChild(link);
    list_item.appendChild(link_par);

    body = document.createElement("p");
    body.className = "body";
    if (item.querySelector('p.result-content') !== null)
      body.innerHTML = item.querySelector('p.result-content').outerHTML;
    else
      body.innerHTML = "";
    list_item.appendChild(body);

    list.appendChild(list_item);
  })
  .declareMethod("clear", function () {
    var list = document.getElementById("mynij-results");
    while (list.firstChild) {
      list.removeChild(list.firstChild);
    }
    list = document.getElementById("searx-results");
    while (list.firstChild) {
      list.removeChild(list.firstChild);
    }
  })
  .declareMethod("cut_description", function (body, key) {
    //function(body, description, key)
    var result,
        max_length = 250,
        key_list = key.split(' '),
        search_key = key;

    function extract_description(description) {
      var regex,
          start,
          end,
          count = 0,
          i;
      if (description.length <= max_length)
        return description;
      regex = new RegExp('(' + search_key + ')', 'i').exec(description);
      if (regex !== null) {
        start = regex.index;
        end = start + regex[0].length;
        i = start;
        while (i > 0 && count < 10) {
          if (description[i] === ' ') {
            count += 1;
            start = i + 1;
          }
          i -= 1;
        }
        if (i === 0)
          start = 0;
        end = max_length + start;
        if (end > description.length)
          end = description.length;
        return description.slice(start, end) + "...";
      }
      return description;
    }

    if (!body)
      return "";
    if (key_list.length > 0)
      search_key = [key].concat(key_list).join("|");
    result = new RegExp(
      '[^;?.?!]*\\s?(' + search_key + ')\\s?[^.?!]*[.?!]', 'i').exec(body);

    if (result === null) {
      //if (description !== "") return description; else....
      return body.slice(0, max_length) + "...";
    }
    else
      return extract_description(result[0]);
  })
  .declareMethod("cut_link", function (link) {
    var url,
        short_url = "",
        page_name,
        ext;

    if (link === undefined)
      return "";
    if (link.length < 70) {
      return link;
    }
    url = new URL(link);
    short_url = url.origin + '/.../';
    page_name = url.pathname.split('/').pop();
    if (page_name.length > 50) {
      ext = page_name.split('.').pop();
      short_url += page_name.slice(0, 40) + '....' + ext;
    } else {
      short_url += page_name;
    }

    return short_url;
  })
  .declareMethod("setSearxMoreLink", function (query_url) {
    var link = this.element.querySelector('.searx-morelink');
    if (link)
      link.href = query_url;
  });

}(window, RSVP, rJS, document, DOMParser, URL));