/* This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
 *    Copyright (C) 2018  idalin<dalin.lin@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
/*
 * Get Metadata from Douban Books api and Google Books api and ComicVine
 * Google Books api document: https://developers.google.com/books/docs/v1/using
 * Douban Books api document: https://developers.douban.com/wiki/?title=book_v2 (Chinese Only)
 * ComicVine api document: https://comicvine.gamespot.com/api/documentation
 */
/* global _, i18nMsg, tinymce */
var dbResults = [];
var ggResults = [];
var cvResults = [];
var gsResults = [];

$(function () {
  var msg = i18nMsg;
  var douban = "https://api.douban.com";
  var dbSearch = "/v2/book/search";
  var dbDone = 0;

  var google = "https://www.googleapis.com";
  var ggSearch = "/books/v1/volumes";
  var ggDone = 0;

  var comicvine = "https://comicvine.gamespot.com";
  var cvSearch = "/api/search/";
  var cvDone = 0;

  var googlescholar = window.location.href.split('/admin/book')[0];
  var gsSearch = "/scholarsearch/"
  var gsDone = 0;

  var showFlag = 0;

  var templates = {
    bookResult: _.template(
      $("#template-book-result").html()
    )
  };

  function populateForm (book) {
    tinymce.get("description").setContent(book.description);
    var uniqueTags = [];
    $.each(book.tags, function(i, el) {
      if ($.inArray(el, uniqueTags) === -1) uniqueTags.push(el);
    });

    var ampSeparatedAuthors = (book.authors || []).join(" & ");
    $("#bookAuthor").val(ampSeparatedAuthors);
    $("#book_title").val(book.title);
    $("#tags").val(uniqueTags.join(","));
    $("#rating").data("rating").setValue(Math.round(book.rating));
    if(book.cover !== null){
      $(".cover img").attr("src", book.cover);
      $("#cover_url").val(book.cover);
    }
    $("#pubdate").val(book.publishedDate);
    $("#publisher").val(book.publisher);
    if (typeof book.series !== "undefined") {
      $("#series").val(book.series);
    }
  }

  function showResult () {
    showFlag++;
    if (showFlag === 1) {
      $("#meta-info").html("<ul id=\"book-list\" class=\"media-list\"></ul>");
    }
    if ((ggDone === 3 || (ggDone === 1 && ggResults.length === 0)) &&
      (dbDone === 3 || (dbDone === 1 && dbResults.length === 0)) &&
      (cvDone === 3 || (cvDone === 1 && cvResults.length === 0)) &&
      (gsDone === 3 || (gsDone === 1 && gsResults.length === 0))) {
      $("#meta-info").html("<p class=\"text-danger\">" + msg.no_result + "</p>");
      return;
    }
    function formatDate (date) {
      var d = new Date(date),
        month = "" + (d.getMonth() + 1),
        day = "" + d.getDate(),
        year = d.getFullYear();

      if (month.length < 2) {
        month = "0" + month;
      }
      if (day.length < 2) {
        day = "0" + day;
      }

      return [year, month, day].join("-");
    }
    function generateID (title) {
      return title.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0).toString().substr(0,12);
    }

    if (ggResults.length > 0) {
      if (ggDone < 2) {
        ggResults.forEach(function(result) {
          var book = {
            id: result.id,
            title: result.volumeInfo.title,
            authors: result.volumeInfo.authors || [],
            description: result.volumeInfo.description || "",
            publisher: result.volumeInfo.publisher || "",
            publishedDate: result.volumeInfo.publishedDate || "",
            tags: result.volumeInfo.categories || [],
            rating: result.volumeInfo.averageRating || 0,
            cover: result.volumeInfo.imageLinks ?
            result.volumeInfo.imageLinks.thumbnail : location + "/../../../static/generic_cover.jpg",
            url: "https://books.google.com/books?id=" + result.id,
            source: {
              id: "google",
              description: "Google Books",
              url: "https://books.google.com/"
            }
          };

          var $book = $(templates.bookResult(book));
          $book.find("img").on("click", function () {
            populateForm(book);
          });

          $("#book-list").append($book);
        });
        ggDone = 2;
      } else {
        ggDone = 3;
      }
    }

    if (gsResults.length > 0) {
      if (gsDone < 2) {
        gsResults.forEach(function(result) {
          var book = {
            id: generateID(result.bib.title),
            title: result.bib.title,
            authors: result.bib.author || [],
            description: result.bib.abstract || "",
            publisher: result.bib.venue || "",
            publishedDate: result.bib.pub_year ? result.bib.pub_year+"-01-01" : "",
            tags: [],
            rating: 0,
            series: "",
            cover: null,
            url: result.pub_url || result.eprint_url || "",
            source: {
              id: "googlescholar",
              description: "Google Scholar",
              link: "https://scholar.google.com/"
            }
          }
          var $book = $(templates.bookResult(book));
          $book.find("img").on("click", function () {
            populateForm(book);
          });

          $("#book-list").append($book);

        });
        gsDone = 2;
      }
      else {
        gsDone = 3;
      }
    }

    if (dbResults.length > 0) {
      if (dbDone < 2) {
        dbResults.forEach(function(result) {
          var seriesTitle = "";
          if (result.series) {
            seriesTitle = result.series.title;
          }
          var dateFomers = result.pubdate.split("-");
          var publishedYear = parseInt(dateFomers[0], 10);
          var publishedMonth = parseInt(dateFomers[1], 10);
          var publishedDate = new Date(publishedYear, publishedMonth - 1, 1);

          publishedDate = formatDate(publishedDate);

          var book = {
            id: result.id,
            title: result.title,
            authors: result.author || [],
            description: result.summary,
            publisher: result.publisher || "",
            publishedDate: publishedDate || "",
            tags: result.tags.map(function(tag) {
              return tag.title.toLowerCase().replace(/,/g, "_");
            }),
            rating: result.rating.average || 0,
            series: seriesTitle || "",
            cover: result.image,
            url: "https://book.douban.com/subject/" + result.id,
            source: {
              id: "douban",
              description: "Douban Books",
              url: "https://book.douban.com/"
            }
          };

          if (book.rating > 0) {
            book.rating /= 2;
          }

          var $book = $(templates.bookResult(book));
          $book.find("img").on("click", function () {
            populateForm(book);
          });

          $("#book-list").append($book);
        });
        dbDone = 2;
      } else {
        dbDone = 3;
      }
    }
    if (cvResults.length > 0) {
      if (cvDone < 2) {
        cvResults.forEach(function(result) {
          var seriesTitle = "";
          if (result.volume.name) {
            seriesTitle = result.volume.name;
          }
          var dateFomers = "";
          if (result.store_date) {
            dateFomers = result.store_date.split("-");
          } else {
            dateFomers = result.date_added.split("-");
          }
          var publishedYear = parseInt(dateFomers[0], 10);
          var publishedMonth = parseInt(dateFomers[1], 10);
          var publishedDate = new Date(publishedYear, publishedMonth - 1, 1);

          publishedDate = formatDate(publishedDate);

          var book = {
            id: result.id,
            title: seriesTitle + " #" + ("00" + result.issue_number).slice(-3) + " - " + result.name,
            authors: result.author || [],
            description: result.description,
            publisher: "",
            publishedDate: publishedDate || "",
            tags: ["Comics", seriesTitle],
            rating: 0,
            series: seriesTitle || "",
            cover: result.image.original_url,
            url: result.site_detail_url,
            source: {
              id: "comicvine",
              description: "ComicVine Books",
              url: "https://comicvine.gamespot.com/"
            }
          };

          var $book = $(templates.bookResult(book));
          $book.find("img").on("click", function () {
            populateForm(book);
          });

          $("#book-list").append($book);
        });
        cvDone = 2;
      } else {
        cvDone = 3;
      }
    }
  }

  function ggSearchBook (title) {
    $.ajax({
      url: google + ggSearch + "?q=" + title.replace(/\s+/gm, "+"),
      type: "GET",
      dataType: "jsonp",
      jsonp: "callback",
      success: function success(data) {
        if ("items" in data) {
          ggResults = data.items;
        }
      },
      complete: function complete() {
        ggDone = 1;
        showResult();
        $("#show-google").trigger("change");
      }
    });
  }

  function dbSearchBook (title) {
    var apikey = "054022eaeae0b00e0fc068c0c0a2102a";
    $.ajax({
      url: douban + dbSearch + "?apikey=" + apikey + "&q=" + title + "&fields=all&count=10",
      type: "GET",
      dataType: "jsonp",
      jsonp: "callback",
      success: function success(data) {
        dbResults = data.books;
      },
      error: function error() {
        $("#meta-info").html("<p class=\"text-danger\">" + msg.search_error + "!</p>" + $("#meta-info")[0].innerHTML);
      },
      complete: function complete() {
        dbDone = 1;
        showResult();
        $("#show-douban").trigger("change");
      }
    });
  }

  function cvSearchBook (title) {
    var apikey = "57558043c53943d5d1e96a9ad425b0eb85532ee6";
    title = encodeURIComponent(title);
    $.ajax({
      url: comicvine + cvSearch + "?api_key=" + apikey + "&resources=issue&query=" + title + "&sort=name:desc&format=jsonp",
      type: "GET",
      dataType: "jsonp",
      jsonp: "json_callback",
      success: function success(data) {
        cvResults = data.results;
      },
      error: function error() {
        $("#meta-info").html("<p class=\"text-danger\">" + msg.search_error + "!</p>" + $("#meta-info")[0].innerHTML);
      },
      complete: function complete() {
        cvDone = 1;
        showResult();
        $("#show-comics").trigger("change");
      }
    });
  }

  function gsSearchBook (title) {
    $.ajax({
      url: googlescholar + gsSearch + title.replace(/\s+/gm,'+'),
      type: "GET",
      dataType: "json",
      success: function success(data) {
        gsResults = data;
      },
      complete: function complete() {
        gsDone = 1;
        showResult();
        $("#show-googlescholar").trigger("change");
      }
    })
  }

  function doSearch (keyword) {
    showFlag = 0;
    dbDone = ggDone = cvDone = 0;
    dbResults = [];
    ggResults = [];
    cvResults = [];
    gsResults = [];
    $("#meta-info").text(msg.loading);
    if (keyword) {
      dbSearchBook(keyword);
      ggSearchBook(keyword);
      cvSearchBook(keyword);
      gsSearchBook(keyword);
    }
  }

  $("#meta-search").on("submit", function (e) {
    e.preventDefault();
    var keyword = $("#keyword").val();
    if (keyword) {
      doSearch(keyword);
    }
  });

  $("#get_meta").click(function () {
    var bookTitle = $("#book_title").val();
    if (bookTitle) {
      $("#keyword").val(bookTitle);
      doSearch(bookTitle);
    }
  });

});