const Geos = require('../modules/geocoder'); 
const Images = require('../modules/images');
const Logger = require('../modules/logger');
const Mongoose = require('mongoose');	

const CruiseSchema = new Mongoose.Schema({
	order: { type: Number, default: 0 },
	location: {
	  address: {
      street1: String,
      street2: String,
      locality: { 
        type: String, 
        index: true 
      },
      region: { 
        type: String, 
        index: true 
      },
      postal: { 
        type: String, 
        index: true 
      },
      country: { 
        type: String, 
        index: true 
      }
	  },
    loc: {
      type: {
        type: String,
        default: 'Point'
      },      
      coordinates: [{
        type: Number,
        default: [0, 0]
      }]
    }
  },
  name: String,
  pic: {
    detail: {
      type: String,
      default: 'cruise/default_detail.png'
    },
    thumb: {
      type: String,
      default: 'cruise/default_thumbnail.png'
    }
  },
  text: String
});

//CruiseSchema.index({ 'location.loc': '2dsphere' });

CruiseSchema.pre('findOneAndUpdate', function (next) {
	var cnt = 0
	var pic;

	if (this.details && this.details.pic) {
		pic = this.details.pic;
		cnt = cnt + (typeof pic.detail === 'object' ? 1 : 0) + (typeof pic.thumb === 'object' ? 1 : 0);
	}		 

	if (cnt > 0) {
		if (typeof pic.detail === 'object') {
			Images.saveCruiseDetailImage(pic.detail, (err, filename) => {
				if (err) {
					Logger.error('[CruiseSchema.pre(save)] There was an error processing the cruise image. [' + err + ']', { error: err });
				}
			
				if (filename) {
					pic.detail = filename;
					cnt -= 1;
					if (cnt === 0) next();
				}
			});
		} 
		
		if (typeof pic.thumb === 'object') {
			Images.saveCruiseThumbnailImage(pic.thumb, (err, filename) => {
				if (err) {
					Logger.error('[CruiseSchema.pre(save)] There was an error processing the cruise image. [' + err + ']', { error: err });
				}
			
				if (filename) {
					pic.thumb = filename;
					cnt -= 1;
					if (cnt === 0) next();
				}
			});
		} 
	} else {
		next();
	}
});

CruiseSchema.pre('save', function (next) {
	var cnt = 0;
	var pic;

	if (this.details && this.details.pic) {
		pic = this.details.pic
		cnt = cnt + (typeof pic.detail === 'object' ? 1 : 0) + (typeof pic.thumb === 'object' ? 1 : 0);
	}		 

	if (cnt > 0) {
		if (typeof pic.detail === 'object') {
			Images.saveCruiseDetailImage(pic.detail, (err, filename) => {
				if (err) {
					Logger.error('[CruiseSchema.pre(save)] There was an error processing the cruise image. [' + err + ']', { error: err });
				}
			
				if (filename) {
					pic.detail = filename;
					cnt -= 1;
					if (cnt === 0) next();
				}
			});
		} 
		
		if (typeof pic.thumb === 'object') {
			Images.saveCruiseThumbnailImage(pic.thumb, (err, filename) => {
				if (err) {
					Logger.error('[CruiseSchema.pre(save)] There was an error processing the cruise image. [' + err + ']', { error: err });
				}
			
				if (filename) {
					pic.thumb = filename;
					cnt -= 1;
					if (cnt === 0) next();
				}
			});
		} 
	} else {
		next();
	}
});

const CruiseModel = Mongoose.model('cruises', CruiseSchema);

module.exports = {	
	
	all: (e) => {
		const promise = new Promise((resolve, reject) => {
			CruiseModel
				.find({})
				.sort({ order: 1 })
				.exec((err, result) => {
					if (err) {
						reject(err);
					}

					if (result) {
						resolve(result);
					}
				});
		});

		promise.then((result) => {
			e.emit('all', null, result);
		})
		.catch((err) => {
			e.emit('all', err, null);
		});
	},

	create: (e, cruises) => {
		var count = cruises.length;
		var errors = [];
		var results = [];
		const promise = new Promise((resolve, reject) => {	
			for (let i = 0; i < cruises.length; i++) {
				var cruise = cruises[i];
				var cruiseInstance = new CruiseModel(cruise);

				cruiseInstance.save((err, result) => {
					if (err) {
						count -= 1;
						errors.push({
							cruise: cruise,
							error: err
						});
						if (count === 0) {
							reject({ results: results, errors: errors });
						}
					}

					if (result) {
						count -= 1;
						results.push(result);
						if (count === 0) {
							resolve({ results: results, errors: errors });
						}
					}
				});
			
			}

		});

		promise.then((result) => {
			e.emit('create', null, result);
		})
		.catch((err) => {
			e.emit('create', err, null);
		});
	},
	
	delete: (e, id) => {
		const promise = new Promise((resolve, reject) => {
			CruiseModel.remove({ _id: id }, (err, result) => {
				if (err) {
					reject(err);
				}

				if (result) {
					resolve(result);
				}
			});
		});

		promise.then((result) => {
			e.emit('delete', null, result);
		})
		.catch((err) => {
			e.emit('delete', err, null);
		});
	},

	find: (e, find) => {
		const promise = new Promise((resolve, reject) => {	
			var query = CruiseModel
				.find(find.find)
				.skip(find.options.skip)
				.limit(find.options.limit)
				.sort(find.options.sort)
				.select(find.select || '')
        .exec((err, results) => {
          if (err) {
            reject(err);
          }

          if (results) {
            resolve(results);
          }
        });
		});

		promise.then((result) => {
			e.emit('find', null, result);
		})
		.catch((err) => {
			e.emit('find', err, null);
		});
	},
		
	get: (e, id) => {
		const promise = new Promise((resolve, reject) => {	
			CruiseModel.findById(id, (err, result) => {
				if (err) {
					reject(err);
				}

				if (result) {
					resolve(result);
				}
			});
		});

		promise.then((result) => {
			e.emit('get', null, result);
		})
		.catch((err) => {
			e.emit('get', err, null);
		});
	},
	
	update: (e, id, cruise) => {
		const promise = new Promise((resolve, reject) => {
			CruiseModel.findOneAndUpdate(
				{ _id: id }, 
				{ $set: cruise },
				{ new: true }, 
				(err, result) => {
					if (err) {
						reject(err);
					}

					if (result) {
						resolve(result);
					}
				});
		});

		promise.then((result) => {
			e.emit('update', null, result);
		})
		.catch((err) => {
			e.emit('update', err, null);
		});
	}
};
