import _User from "./_User.js";
import _Message from "./_Message.js";
import isUndefined from "./util/isUndefined.js";
import isArray from "./util/isArray.js";
import remove from "./util/removeElement.js";
//import filterCollection from "./lodash-es/filter.js";

var _Item = {};

_Item.collection = [];

_Item.priceOf = function(item){
  if(isUndefined(item.price_user)){
    if(_User.isGold()){
      return item.price_gold;
      }
    else{
      return item.price_silver;
      }
    }
  else{
    return item.price_user;
    }
  };

/*
 Rationale for model-specific accessors like this, instead of directly using the general `_DB` module:
 Each model, whether for reads or writes on the server, may have special logic.
 For example, items. If a user isn't logged-in, only certain brands may be returned by the server.
 Another example, images. When a new image record is inserted into the DB, it saves the binary image data to a file, makes thumbnails, and saves the files' paths in the record, and returns the entire record to the client to update the path info.
 These can be accomplished by having a very smart client `_DB` module, which can direct each individual step on the server (e.g. make thumbnail, save to file, etc.).
 However, it's dangerous for a client to have the ability to "send code" to the server. The logic should reside on the server, only invoked by the client.
 Another problem with this is that it would require a lot of round-trips -- one for each step. 
 Another problem is that it's harder to implement atomic modifications. For example, if making a thumbnail fails, the entire image record is discarded from the DB. (This isn't actually the desired behavior, this is just for illustration.)
 In conclusion, we've opted for model-specific getters/setters, both on client and on server.
 
 However, the model-specific logic on both ends should still make sure to integrate data they receive into the DB, to keep all data in one place, and not have a bunch of copies of data with the same 'id' but different properties.
 */
_Item.getItems = function(filter){
  return m.request({
    method:"POST",
    url:"/cgi/itemsbyfilter",
    body: {
      session_hash: _User.session_hash,
      filter:filter
      }})
  .then(function(res){
    if(res.success === true){
      // the server encodes an empty set as an Object instead of Array, so we have to detect it:
      if(!isArray(res.items)){
        res.items = [];
        }
      res.items.forEach(function(item, index){
        if(!isArray(item.image_ids)){
          item.image_ids = [];
          }
        _DB.integrateAllReturnIds(item.image_ids); // converts objects to ids in-place
        res.items[index] = _DB.integrate(item);  // TODO: ensure all integrations are captured and return, as this is, so everything refers to the same record in the DB
        });
      return res.items;
      }
    });
  };

_Item.getFullItemInfo = function(item){
  return m.request({
    method:"POST",
    url:"/cgi/fulliteminfo",
    body: {
      item_id: item.id
      }})
  .then(function(res){
    var item = _DB.integrate(res.item);
    return item;
    });
  };

_Item.searchByString = function(search_string){
  return m.request({
    method:"POST",
    url:"/cgi/itemsbystring",
    body: {
      session_hash: _User.session_hash,
      search_string: search_string
      }});
  };

_Item.addImage = function(item, image){
  var image_index = item.image_ids.push(image) - 1;
  return m.request({
    method:"POST",
    url:"/cgi/addimagetoitem",
    body: {
      session_hash: _User.session_hash,
      item_id: item.id,
      image_base64: image.src_base64,
      original_filename: image.original_filename
      },
    config: function(xhr){
      image.is_uploading = true;
      image.progress = 0;
      xhr.addEventListener('progress', function(e){
        image.progress = e.loaded / e.total;
        });
      }
    })
  .then(function(res){
    delete image.is_uploading;
    delete image.progress;
    if(res.success === true){
      _Message.addSuccess("Uploaded "+image.original_filename);
      // At this point, `image` is still not its own record in `_DB`
      // `image` has a large `src_base64` property, whereas `res.image` has a bunch of properties which were set by the server, namely the paths to the different thumbnails of the image, and the original
      // Therefore, we choose to integrate `res.image` into `_DB`, and simply attach
      item.image_ids[image_index] = res.image.id;
      res.image = _DB.integrate(res.image);
      return res.image;
      }
    else{
      res.errors.forEach(function(err){
        _Message.addError("Error uploading "+image.original_filename+": "+err);
        });
      }
    });
  };

_Item.loadImages = function(item){
  return m.request({
    method:"POST",
    url:"/cgi/itemimages",
    body: {
      session_hash: _User.session_hash,
      item_id: item.id
      }})
  .then(function(res){
    if(res.success === true){
      var images;
      if(isArray(res.images)){
        images = _DB.integrateAll(res.images);
        item.image_ids = res.images.map(function(i){ return i.id; });
        }
      else{
        item.image_ids = [];
        images = [];
        }
      return images;
      }
    else{
      res.errors.forEach(function(err){
        _Message.addError("Error uploading "+image.original_filename+": "+err);
        });
      }
    });
  };

_Item.deleteImage = function(item, image){
  remove(item.image_ids, image.id);
  _DB.removeRecord(image);
  return m.request({
    method:"POST",
    url:"/cgi/deleteitemimage",
    body: {
      session_hash: _User.session_hash,
      item_id: item.id,
      image_id: image.id
      }});
  };

export default _Item;