import { config, configRoutes } from './StaticData.js';
import routeOptions from './routeOptions.json'
import Services from '@helpers/Services/Services.js';
import {addedSite, updatedSite, removedNewSite, deletedSite, addedNewRoute, updatedRoute, sortedRoutes, deletedRoute} from './helpers.js';
import {isEmpty, dissoc} from 'ramda';
import RoutesClass from "@helpers/server-routes/Routes.js";

const routerManager = new RoutesClass(import.meta.env.VITE_API_ADDR, configRoutes)
const services = new Services(import.meta.env.VITE_API_ADDR, config)

const initState = {
  sites: [],
  sitesState: "loading",
  isSaveData: false,
  selectedSite: null,

  routes: [],
  newRoute: null,
  routesState: "await",
};

const state = {
  ...initState
};

const getters = {
  isSaveData:  (state) => state.isSaveData,
  sites:        (state) => state.sites,
  routes:       (state) => state.routes.filter(({action}) => !["remove", "delete"].includes(action)),
  routesState:  (state) => state.routesState,
  sitesState:   (state) => state.sitesState,
  routeOptions: () => routeOptions,
  selectedSite: (state) => state.selectedSite,
  newRoute:     (state) => state.newRoute,
};

const mutations = {
  setIsSaveData: (state, payload) => state.isSaveData = payload,
  setSites: (state, payload) => state.sites = payload,
  setSitesState: (state, payload) => state.sitesState = payload,
  setSelectedSite: (state, payload) => state.selectedSite = payload,
  setRoutes: (state, payload) => state.routes = payload,
  setRoutesState: (state, payload) => state.routesState = payload,
  setNewRoute: (state, payload) => state.newRoute = payload,
};

const actions = {
  addNewSiteLayout: ({commit, getters}) => {
    const newSite = {"port": "", "name": "", id: -1}
    commit('setSites', [newSite,...getters.sites])
    commit('setSelectedSite', newSite)
    commit('setRoutes', [])
    commit('setRoutesState', "active")
  },
  createNewSite: async ({dispatch, commit, getters, state}, payload) => {
    commit('setIsSaveData', false)
    commit('setSelectedSite', null)
    const newSite = await services.createService(payload)
    const updatedSites = addedSite(newSite, getters.sites)
    if (!isEmpty(updatedSites)) {
      const newSite = updatedSites[0]
      const updatedRoutes = addedNewRoute(newSite, state.routes)
      commit('setRoutes', updatedRoutes)
      dispatch('updateRoutesWithApi', newSite)
      return commit('setSites', updatedSites)
    }
  },
  breakeAddingSite: ({commit}) => {
    commit('setSelectedSite', null)
  },
  uploadSites: async ({commit}) => {
    const sites = await services.getServices()
    commit('setSites', sites)
    commit('setSitesState', 'active')
  },
  editSelectedSite: async ({commit, getters}, payload) => {
    const selectedSite = getters.selectedSite
    selectedSite[payload.key] = payload.value
    commit('setSelectedSite', selectedSite)
  },
  saveSite: async ({commit, getters}, payload) => {
    commit('setIsSaveData', false)
    commit('setSelectedSite', null)
    const editedSite = await services.updateService(payload)
    const updatedSites = !isEmpty(editedSite) ? updatedSite(editedSite, getters.sites) : getters.sites
    commit('setSites', updatedSites)
  },
  breakSavingSite: ({commit}) => {
    commit('setSelectedSite', null)
    commit('setRoutesState', "await")
  },
  removeSite: async ({commit, getters}, id) => {
    const deletedSiteId = await services.deleteService(id)
    const updatedSites = deletedSite(deletedSiteId, getters.sites)
    if (!isEmpty(updatedSites)) return commit('setSites', updatedSites)
  },
  uploadSiteRoutes: async ({commit, getters}, siteProps) => {
    const sites = removedNewSite(getters.sites)
    commit('setSites', sites)
    commit('setSelectedSite', siteProps)
    commit('setRoutesState', "loading")
    let routes = await routerManager.getRouterById(siteProps.id)
    routes = sortedRoutes(routes)
    commit('setRoutes', routes)
    commit('setRoutesState', "active")
  },
  addNewRouteLayout: ({commit, getters}) => {
    const newRoute = {
      "path": null,
      "role": null,
      id: Math.floor(100000 + Math.random() * 900000),
      action: "create",
      server_id: getters.selectedSite.id
    }
    commit('setNewRoute', newRoute)
    commit('setRoutes', [newRoute, ...state.routes])
  },
  updateRouteRow: ({commit, state}, editRoute) => {
    const editedRoute = state.newRoute ? {...state.newRoute, ...editRoute} : editRoute
    const updatedRoutes = updatedRoute(editedRoute, state.routes)
    if (state.newRoute && state.newRoute.id === editRoute.id) {
      commit('setNewRoute', {...state.newRoute, ...editRoute})
    }
    commit('setRoutes', updatedRoutes)
  },
  updateRoutesWithApi: async ({commit, state}, payload) => {
    commit('setRoutesState', "loading")
    if (!state.routes || isEmpty(state.routes)) return commit('setRoutesState', "await")
    let updatedRoutes = state.routes.filter(({action}) => action)
    updatedRoutes = updatedRoutes.map((el) => {
      if (el.action === "create") return dissoc('id', el)
      return  el
    })
    await routerManager.updateGroupRoutes(updatedRoutes)
    let routes = await routerManager.getRouterById(payload.id)
    routes = sortedRoutes(routes)
    commit('setRoutes', routes)
    commit('setRoutesState', "await")
    commit('setNewRoute', null)
  },
  removeRoute: ({commit, state}, {id}) => {
    const updatedRoutes = deletedRoute(id, state.routes)
    commit('setRoutes', updatedRoutes)
  },
  resetStore: ({state}) => {
    Object.entries(initState).forEach(([k,v]) => {
      state[k] = v
    })
  },
};

export const store = {
  namespaced: true,
  state,
  getters,
  mutations,
  actions,
};
