import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import app from '../../main' // import the instance
import checkResponse from '@/utils/checkResponse'
import parserFilters from '@/utils/parserFilters'
import parserSlug from '@/utils/parserSlug'

Vue.use(Vuex)

const state = {
  purchaseOrders: [],
  purchaseOrder: {
    details: []
  },
  pagination: {
    currentPage: 1,
    perPage: 5,
    totalPurchaseOrders: 0,
    totalPages: 0
  },
  purchaseOrdersCatalog: {
    customers: [],
    payment_methods: []
  },
  filterParams: '',
  isModalVisible: false
}

const mutations = {
  INIT_PURCHASE_ORDER_DETAIL (state, payload) {
    state.purchaseOrder = payload
  },
  SET_PURCHASE_ORDERS (state, payload) {
    state.purchaseOrders = payload.data

    state.pagination = {
      currentPage: payload.current_page,
      perPage: payload.per_page,
      totalPurchaseOrders: payload.total,
      totalPages: payload.last_page
    }
  },
  ADD_PURCHASE_ORDER (state, payload) {
    state.purchaseOrders.unshift(payload)
  },
  UPDATE_PURCHASE_ORDER (state, payload) {
    state.purchaseOrder = payload
  },
  UPDATE_PURCHASE_ORDER_ACTION (state, payload) {
    const idx = state.purchaseOrders.findIndex(u => u.id === payload.id)

    if (idx >= 0) {
      Vue.set(state.purchaseOrders, idx, payload)
    }
  },
  DELETE_PURCHASE_ORDER (state, payload) {
    const idx = state.purchaseOrders.findIndex(u => u.id === payload.id)

    if (idx >= 0) {
      Vue.delete(state.purchaseOrders, idx)
    }
  },
  DELETE_PURCHASE_ORDERS (state, payload) {
    for (let id of payload.ids) {
      const idx = state.purchaseOrders.findIndex(u => u.id === id)

      if (idx >= 0) {
        Vue.delete(state.purchaseOrders, idx)
      }
    }
  },
  ADD_PURCHASE_ORDER_DETAIL (state, payload) {
    state.purchaseOrder.details.unshift(payload)
  },
  UPDATE_PURCHASE_ORDER_DETAIL (state, { payload, idx }) {
    if (idx >= 0) {
      Vue.set(state.purchaseOrder.details, idx, payload)
    }
  },
  DELETE_PURCHASE_ORDER_DETAIL (state, idx) {
    if (idx >= 0) {
      Vue.delete(state.purchaseOrder.details, idx)
    }
  },
  DELETE_PURCHASE_ORDER_DETAILS (state, payload) {
    for (let idx of payload.indexes) {
      if (idx >= 0) {
        Vue.delete(state.purchaseOrder.details, idx)
      }
    }
  },
  SET_PURCHASE_ORDER (state, payload) {
    state.purchaseOrder = payload.data
  },
  SET_MODAL_VISIBLE (state, payload) {
    state.isModalVisible = payload
  },
  SET_FILTER_PARAMS (state, payload) {
    state.filterParams = payload
  },
  SET_CATALOG (state, { object, payload }) {
    state.purchaseOrdersCatalog[object] = payload.data
  }
}

const actions = {
  initPurchaseOrder ({ commit }, payload) {
    commit('INIT_PURCHASE_ORDER_DETAIL', payload)
  },
  async loadPurchaseOrders ({ commit }, payload) {
    app.$Progress.start()
    try {
      const response = await axios.get(`purchase-orders?page=${payload.page}${state.filterParams}`)
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('SET_PURCHASE_ORDERS', response.data)
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  async addPurchaseOrder ({ commit }, payload) {
    const purchaseOrder = {
      folio: 'ss',
      customer_id: payload.customer_id,
      details: payload.details,
      status: payload.status,
      subtotal: 2.2,
      total: 4.5
    }

    app.$Progress.start()

    try {
      const response = await axios.post('purchase-orders', purchaseOrder)
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('ADD_PURCHASE_ORDER', response.data)
        commit('SET_ACCEPT_ALERT', { color: 'success', title: 'strings.purchase_orders', text: 'front.added_successfully', icon: 'checkmark-circle-outline' }, { root: true })
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  async editPurchaseOrder ({ commit }, payload) {
    const purchaseOrder = {
      folio: payload.folio,
      customer_id: payload.customer_id,
      details: payload.details,
      status: payload.status,
      subtotal: payload.subtotal,
      total: payload.total
    }

    app.$Progress.start()

    try {
      const response = await axios.put(`purchase-orders/${payload.id}`, purchaseOrder)
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('UPDATE_PURCHASE_ORDER', response.data)
        commit('SET_ACCEPT_ALERT', { color: 'success', title: 'strings.purchase_orders', text: 'front.updated_successfully', icon: 'checkmark-circle-outline' }, { root: true })
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  async deletePurchaseOrder ({ commit }, payload) {
    app.$Progress.start()
    try {
      const response = await axios.delete(`purchase-orders/${payload.id}`)
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('DELETE_PURCHASE_ORDER', payload)
        commit('SET_ACCEPT_ALERT', { color: 'success', title: 'strings.purchase_orders', text: 'front.deleted_successfully', icon: 'checkmark-circle-outline' }, { root: true })
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  async deletePurchaseOrders ({ commit }, payload) {
    app.$Progress.start()
    try {
      const response = await axios.delete(`purchase-orders/delete`, { params: { ids: payload.ids } })
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('DELETE_PURCHASE_ORDERS', payload)
        commit('SET_ACCEPT_ALERT', { color: 'success', title: 'strings.purchase_orders', text: 'front.deleted_successfully', icon: 'checkmark-circle-outline' }, { root: true })
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  async addPurchaseOrderDetail ({ commit }, payload) {
    app.$Progress.start()
    const PurchaseOrderDetail = {
      quantity: parseInt(payload.quantity),
      unit_price: parseFloat(payload.unit_price).toFixed(2),
      total: 1
    }
    commit('ADD_PURCHASE_ORDER_DETAIL', PurchaseOrderDetail)
    commit('SET_MODAL_VISIBLE', false)
    app.$Progress.finish()
  },
  async editPurchaseOrderDetail ({ commit }, payload) {
    app.$Progress.start()
    const PurchaseOrderDetail = {
      id: payload.detail.id,
      quantity: parseInt(payload.detail.quantity),
      unit_price: parseFloat(payload.detail.unit_price).toFixed(2),
      total: 1
    }
    commit('UPDATE_PURCHASE_ORDER_DETAIL', { payload: PurchaseOrderDetail, idx: payload.index })
    commit('SET_MODAL_VISIBLE', false)
    app.$Progress.finish()
  },
  async deletePurchaseOrderDetail ({ commit }, payload) {
    app.$Progress.start()
    commit('DELETE_PURCHASE_ORDER_DETAIL', payload.index)
    app.$Progress.finish()
  },
  async deletePurchaseOrderDetails ({ commit }, payload) {
    app.$Progress.start()
    commit('DELETE_PURCHASE_ORDER_DETAILS', payload)
    app.$Progress.finish()
  },
  async loadPurchaseOrder ({ commit }, payload) {
    app.$Progress.start()
    try {
      const response = await axios.get(`purchase-orders/${payload.id}`)
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('SET_PURCHASE_ORDER', response.data)
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  async actionPurchaseOrder ({ commit }, payload) {
    app.$Progress.start()
    try {
      const response = await axios.put(`purchase-orders/${payload.id}/${payload.action}`)
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('UPDATE_PURCHASE_ORDER', response.data)
        commit('UPDATE_PURCHASE_ORDER_ACTION', response.data)
        commit('SET_ACCEPT_ALERT', { color: 'success', title: 'strings.purchase_orders', text: `purchase_orders.${payload.action}`, icon: 'checkmark-circle-outline' }, { root: true })
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  printReport ({ commit }, payload) {
    app.$Progress.start()
    try {
      window.open(axios.defaults.baseURL + '/purchase-orders/export?' + state.filterParams)
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  printReportRecord ({ commit }, payload) {
    app.$Progress.start()
    try {
      window.open(`${axios.defaults.baseURL}/purchase-orders/${payload.id}/export`)
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  applyFilter ({ commit }, payload) {
    const filter = parserFilters(payload)
    commit('SET_FILTER_PARAMS', filter)
  },
  clearFilter ({ commit }, payload) {
    const filter = ''
    commit('SET_FILTER_PARAMS', filter)
  },
  async loadCatalog ({ commit }, payload) {
    let url = parserSlug(payload.url)
    app.$Progress.start()
    try {
      const response = await axios.get(`${url}${payload.filter}`)
      const checkErrors = checkResponse(response)

      if (checkErrors) {
        app.$Progress.fail()
        commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: checkErrors.message }, { root: true })
      } else {
        commit('SET_CATALOG', { object: payload.url, payload: response.data })
      }
    } catch (e) {
      app.$Progress.fail()
      commit('SET_ALERT_MESSAGE', { color: 'danger', title: 'errors.connection_error', text: 'errors.generic_error' }, { root: true })
    } finally {
      app.$Progress.finish()
    }
  },
  loadCatalogAux ({ commit }, payload) {
    commit('SET_CATALOG', { object: payload.url, payload: payload })
  },
  setModalVisible ({ commit }, payload) {
    commit('SET_MODAL_VISIBLE', payload)
  }
}

const getters = {
  purchaseOrders: state => state.purchaseOrders,
  purchaseOrder: state => state.purchaseOrder,
  purchaseOrdersCatalog: state => state.purchaseOrdersCatalog,
  pagination: state => state.pagination,
  isModalVisible: state => state.isModalVisible,
  filterParams: state => state.filterParams
}

export default {
  namespaced: true,
  state,
  mutations,
  actions,
  getters
}
