var AppDispatcher = require('../dispatcher/appDispatcher');
var EventEmitter = require('events').EventEmitter;
var CartConstants = require('../constants/cartConstants');
var CartActions = require('../actions/cartActions');
var NavigationActions = require('../actions/navigationActions');
var ItemInCart = require('../models/itemInCart');
var ItemInCartCollection = require('../models/itemInCartCollection');
var ItemCollection = require('../models/itemCollection');
var DeliveryDestination = require('../models/deliveryDestination');
var OrderConfirmation = require('../models/orderConfirmation');
var Place = require('../models/place');
var Validation = require('../utils/validation');

var _ = require('underscore');

var states = {}

var _itemsInCart = new ItemInCartCollection();
var _itemsForDisplay = new ItemCollection();
_itemsForDisplay.setFromCart(true);

var _deliveryDestination = new DeliveryDestination();
var _deliveryDestinationErrors = {};
var _deliveryCosts = new Place({
    postalCode: _deliveryDestination.get('place')
})

var _addressColapsed = false;


var supportedPlaces = [
{
    "code": "-12",
    "placeLabel": "Izaberite mjesto"
}, {
    "code": "-13",
    "placeLabel": "-------------------------------"
}, {
    "code": " 71000",
    "placeLabel": "Sarajevo"
}, {
    "code": " 71103",
    "placeLabel": "Sarajevo, Centar"
}, {
    "code": " 71160",
    "placeLabel": "Sarajevo, Novi Grad"
}, {
    "code": " 71120",
    "placeLabel": "Sarajevo, Novo Sarajevo"
}, {
    "code": " 71140",
    "placeLabel": "Sarajevo, Stari Grad"
}, {
    "code": " 71210",
    "placeLabel": "Ilidža"
}, {
    "code": " 71320",
    "placeLabel": "Vogošća"
}];

var _cartDataLoadCalled = false;

var nameOfThePlace = function(code) {
  for(var i=0; i<supportedPlaces.length; i++ ) {
    var place = supportedPlaces[i];
    if (place.code === code) {
      return place.placeLabel;
    }
  }
  return "";
}

var loadCart = function() {

    _itemsInCart.fetch({
        success: function() {
            states = {}
            for (var i = 0; i < _itemsInCart.models.length; i++) {
                var itemInCart = _itemsInCart.models[i];
                states[itemInCart.get('item_id')] = itemInCart;
            }
            _itemsForDisplay.fetch({
                success: function() {
                    CartActions.dataLoaded();

                    _deliveryDestination.fetch({
                        success: function() {
                            validateDeliveryDestinationForm();
                            collapseAddressIfNeeded();
                            fetchPlace();
                            CartActions.dataLoaded();
                        }
                    });
                }
            });
        }
    });

    _cartDataLoadCalled = true;
};

var collapseAddressIfNeeded = function () {
  if(isDeliveryDestinationValid()) {
    _addressColapsed = true;
  } else {
    _addressColapsed = false;
  }
}

var fetchPlace = function() {
    _deliveryCosts = new Place({
        postalCode: _deliveryDestination.get('place')
    })
    _deliveryCosts.fetch({
        success: function() {
            CartActions.dataLoaded();
        }
    })

}


var saveCartStateForItem = function(itemId) {
    var item = CartStore.getStateFor(itemId);
    item.save({
        success: function() {
            loadCart();
        }
    });
};

/* need it for delete - will delete it later
 */
var takeItemOut = function(itemId) {

    var state = states[itemId] || new ItemInCart({
        item_id: itemId,
        count: 0
    })
    if (state.get('count') > 0) {
        // state.set('count', state.get('count') - 1);
        state.set('count', 0);
    }

    states[itemId] = state;
    saveCartStateForItem(itemId);
};

var setItemCount = function(itemId, count) {
    var state = states[itemId] || new ItemInCart({
        item_id: itemId,
        count: 0
    });

    if (count === "") {
        state.set('count', "");
        CartStore.emitChange();
        return;
    }

    var cnt = parseInt(count);

    if (isNaN(cnt) || cnt <= 0) {
        cnt = 1;
    }

    state.set('count', cnt);

    states[itemId] = state;
    saveCartStateForItem(itemId);
    // CartStore.emitChange();
};

var addNItems = function(item, count) {

    var itemId = item.get('id');
    var state = states[itemId] || new ItemInCart({
        item_id: itemId,
        count: 0
    })

    _itemsForDisplay.add(item);

    var realCount = state.get('count') + count;

    // remove if we choose to support more than
    // 10 items of single type in cart
    if (realCount > 10) {
        realCount = 10;

    }
    state.set('count', realCount);

    states[itemId] = state;
    saveCartStateForItem(itemId);
}

var changeDeliveryDestinationProperty = function(property, value) {
    _deliveryDestination.set(property, value);

    if (property === 'place') {
        fetchPlace();
    }
    validateDeliveryDestinationForm();
};


var confirmOrder = function() {

    var oc = new OrderConfirmation({
        hamo: 'meho'
    });
    oc.save({
        b: 'b'
    }, {
        success: function() {

            NavigationActions.goToThankYou();
            loadCart();
        }
    });
};


var saveDeliveryDestination = function() {
    _deliveryDestination.save(null, {
        success: function() {

            confirmOrder();
        }
    })
};

var validateDeliveryDestinationForm = function() {
    _deliveryDestinationErrors = {};

    var nameRegex = /.+\s+.+/i;
    if (Validation.safeString(_deliveryDestination.get('name')).search(nameRegex) < 0) {
        _deliveryDestinationErrors['name'] = "I prezime i ime su obavezni";
    }

    var addressRegex = /.+\s+.+/i;
    if (Validation.safeString(_deliveryDestination.get('address')).search(addressRegex) < 0) {
        _deliveryDestinationErrors['address'] = "Adresa mora biti ispravna";
    }

    var emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/i;
    if (Validation.safeString(_deliveryDestination.get('email')).search(emailRegex) < 0) {
        _deliveryDestinationErrors['email'] = "Email mora biti ispravno upisan";
    }

    var phoneRegex = /^[\d\s-]{8,12}$/i;
    if (Validation.safeString(_deliveryDestination.get('phone')).search(phoneRegex) < 0) {
        _deliveryDestinationErrors['phone'] = "Telefon mora biti ispravan";
    }

    var placeRegex = /^\s{0,1}\d{5}$/i;
    if (Validation.safeString(_deliveryDestination.get('place')).search(placeRegex) < 0) {
        _deliveryDestinationErrors['place'] = "Mjesto mora biti izabrano";
    }

    var requiredFields = ["name", "email", "place", 'address', 'phone'];
    for (var i in requiredFields) {
        var value = _deliveryDestination.get(requiredFields[i]);
        if (value === undefined || value === null || value === "") {
            // if it's required there will be a star there
            _deliveryDestinationErrors[requiredFields[i]] = "*";
        }
    }

}


var isDeliveryDestinationValid = function() {
        return Object.getOwnPropertyNames(_deliveryDestinationErrors).length === 0;
    }
    // Extend CartStore with EventEmitter to add eventing capabilities
var CartStore = _.extend({}, EventEmitter.prototype, {

    dataStartedLoading: function() {
        return _cartDataLoadCalled;
    },

    getStateFor: function(itemId) {

        var state = states[itemId] || new ItemInCart({
            item_id: itemId,
            count: 0
        })
        return state
    },

    getSupportedPlaces: function() {
      return supportedPlaces;
    },

    getWholeCartState: function() {

        var numberOfItems = 0;

        for (key in states) {
            if (states.hasOwnProperty(key)) {
                var value = states[key];
                if (value.get('count') > 0) {
                    numberOfItems += value.get('count');
                }
            }
        };

        var state = {
            count: numberOfItems,
            items: _itemsForDisplay,
            itemCounts: states,
            deliveryDestination: _deliveryDestination,
            deliveryDestinationErrors: _deliveryDestinationErrors,
            isDeliveryDestinationValid: isDeliveryDestinationValid(),
            deliveryCosts: _deliveryCosts,
            destinationValid: isDeliveryDestinationValid()
        };
        return state;
    },

    // Emit Change event
    emitChange: function() {
        this.emit('change');
    },

    // Add change listener
    addChangeListener: function(callback) {
        this.on('change', callback);
    },

    // Remove change listener
    removeChangeListener: function(callback) {
        this.removeListener('change', callback);
    },

    isDeliveryDestinationValid: isDeliveryDestinationValid,

    isAddressColapsed: function() {
      return _addressColapsed;

    },

    getHumanReadableAddress: function() {
        var address = [];
        address.push(_deliveryDestination.get('name'));
        address.push(_deliveryDestination.get('address'));
        address.push(_deliveryDestination.get('place') + " " + nameOfThePlace(_deliveryDestination.get('place')));
        address.push("Bosna i Hercegovina");
        address.push("+387" + _deliveryDestination.get('phone'))
        address.push(_deliveryDestination.get('email'))

        return address;
    }

});


// Register callback with AppDispatcher
AppDispatcher.register(function(payload) {
    var action = payload.action;
    var text;

    switch (action.actionType) {
        case CartConstants.LOAD_CART_CONTENTS:
            loadCart();
            break;
        case CartConstants.TAKE_ITEM_OUT:
            takeItemOut(action.itemId);
            break;
        case CartConstants.CART_DATA_LOADED:
            // do nothing - just emmit change
            break;
        case CartConstants.SAVE_CART_STATE_FOR_ITEM:
            if (isDeliveryDestinationValid()) {
                saveCartStateForItem(action.itemId);
            }
            break;
        case CartConstants.CHANGE_DELIVERY_DESTINATION_PROPERTY:
            changeDeliveryDestinationProperty(action.propertyName, action.value)
            break;
        case CartConstants.CONFIRM_DELIVERY:
            saveDeliveryDestination();
            break;
        case CartConstants.ADD_N_ITEMS:
            addNItems(action.item, action.count);
            break;
        case CartConstants.SET_ITEM_COUNT:
            setItemCount(action.itemId, action.count);
            break;
        case CartConstants.SET_ADDRESS_COLAPSED:
            _addressColapsed = action.isColapsed
            break;
        default:
            return true;
    }

    // If action was responded to, emit change event
    CartStore.emitChange();
    return true;

});

module.exports = CartStore;