import {toRaw} from 'vue'
import {searchModes, leftTopButtons, rightTopButtons, selects, selectors, charts, dataMachines, dataMount, pagination, machineInfo, reportPacks, report, packStructure, multiReport, multiPackStructure} from './StaticData'
import { chartsSetup } from '@/store/hooks/Echarts/staticData.js';
import { prepareSelects, mergedMachines, setUpdatedDataMachines, colorSelection, loadingPagination, setPagination } from './helpers';
import { loadingChartsData, setBarTypesChart, setNextLayoutGroupByKey, setBeforeLayoutGroupByData, typesCharts } from './helpersCharts';
import { fetchColumn, prepareSetPackColumns } from '@organisms/PackColumns';
import { get } from '../apiHelpers';
import {equals, isEmpty, uniq} from 'ramda'

const initState = {
  leftTopButtons: leftTopButtons,
  rightTopButtons: rightTopButtons,
  searchModes: searchModes,
  pagination: pagination,
  toggleFilter: false,
  openMenuChart: false,
  initHistory: false,

  selectedSearchMode: searchModes[0],
  selectedMode: leftTopButtons[0].key,
  selectedSelects: {},
  activeFilterBtn: null,
  activeChartData: null,
  activeMenuChartData: {openMenuChart: false},
  selectedPackStruct: null,
  selectedPackMode: 'askr_logs',

  searchValue: '',
  selectedData: [],
  selectsData: [],
  machinesDataDefault: [],
  machinesData: [],
  tableData: [],
  chartsData: [],
  chartsMountData: [],
  mapData: null,
  machineInfo: null,
  reportPacks: [],
  structPackDefault: [],
  selectPackStructs: [],
  packData: {},

  historyData: [],
  historyMachines: [],
  legendFiltersParams: [],
};

const state = {
  ...initState
};

const getters = {
  pages: (state) => state.pages,
  searchModes: (state) => state.searchModes,
  leftTopButtons: (state) => state.leftTopButtons,
  rightTopButtons: (state) => state.rightTopButtons,
  toggleFilter: (state) => state.toggleFilter,
  openMenuChart: (state) => state.openMenuChart,
  initHistory: (state) => state.initHistory,

  selectedPage: (state) => state.selectedPage,
  selectedSearchMode: (state) => state.selectedSearchMode,
  selectedMode: (state) => state.selectedMode,
  selectedSelects: (state) => state.selectedSelects,
  activeFilterBtn: (state) => state.activeFilterBtn,
  activeChartData: (state) => state.activeChartData,
  activeMenuChartData: (state) => state.activeMenuChartData,
  selectedPackStruct: (state) => state.selectedPackStruct,
  selectedPackMode: (state) => state.selectedPackMode,

  searchValue: (state) => state.searchValue,
  selectedData: (state) => state.selectedData,
  selectsData: (state) => state.selectsData,
  machinesDataDefault: (state) => state.machinesDataDefault,
  machinesData: (state) => state.machinesData,
  tableData: (state) => state.tableData,
  chartsData: (state) => state.chartsData,
  chartsMountData: (state) => state.chartsMountData,
  historyData: (state) => state.historyData,
  historyMachines: (state) => state.historyMachines,
  legendFiltersParams: (state) => state.legendFiltersParams,
  pagination: (state) => state.pagination,
  mapData: (state) => state.mapData,
  machineInfo: (state) => state.machineInfo,
  reportPacks: (state) => state.reportPacks,
  selectPackStructs: (state) => state.selectPackStructs,
  packData: (state) => state.packData,
};

const mutations = {
  setPage: (state, updval) =>  state.selectedPage = updval,
  setToggleFilter: (state) =>  state.toggleFilter = !state.toggleFilter,
  setOpenMenuChart: (state, updval) =>  state.openMenuChart = updval,
  setInitHistory: (state, updval) =>  state.initHistory = updval,

  setSearchMode: (state, updval) =>  state.selectedSearchMode = updval,
  setSelectedMode: (state, updval) =>  state.selectedMode = updval,
  setSelectedSelects: (state, updval) =>  state.selectedSelects = updval,
  setSelectedMachines: (state, updval) =>  state.selectedMachines = updval,
  setActiveFilterBtn: (state, updval) =>  state.activeFilterBtn = updval,
  setActiveChartData: (state, updval) => state.activeChartData = updval,
  setActiveMenuChartData: (state, updval) => state.activeMenuChartData = updval,
  setSelectedPackStruct: (state, updval) => state.selectedPackStruct = updval,
  setSelectedPackMode: (state, updval) => state.selectedPackMode = updval,

  setSelectsData: (state, updval) =>  state.selectsData = updval,
  setSearchValue: (state, updval) =>  state.searchValue = updval,
  setSelectedData: (state, updval) =>  state.selectedData = updval,
  setMachinesDataDefault: (state, updval) => state.machinesDataDefault = updval,
  setMachinesData: (state, updval) => state.machinesData = updval,
  setTableData: (state, updval) => state.tableData = updval,
  setChartsData: (state, updval) => state.chartsData = updval,
  setChartsDataMount: (state, updval) => state.chartsMountData = updval,
  setHistoryData: (state, updval) => state.historyData = updval,
  setHistoryMachines: (state, updval) => state.historyMachines = updval,
  setLegendFiltersParams: (state, updval) => state.legendFiltersParams = updval,
  setPagination: (state, updval) => state.pagination = updval,
  setMapData: (state, updval) => state.mapData = updval,
  setMachineInfo: (state, updval) => state.machineInfo = updval,
  setReportPacks: (state, updval) => state.reportPacks = updval,
  setStructPackDefault: (state, updval) => state.structPackDefault = updval,
  setSelectPackStructs: (state, updval) => state.selectPackStructs = updval,
  setPackData: (state, updval) => state.packData = updval,
  resetStore: (state) => {
    Object.entries(initState).forEach(([k,v]) => {
      state[k] = v
    })
  },
};


const actions = {
  uploadData: async ({commit, getters, state}, externalParams) => {
    try{
      // const machinesData = toRaw(getters.machinesData)
      // const machinesDataDefault = toRaw(state.machinesDataDefault)
      const pagination = toRaw(getters.pagination)
      // const chartsData = toRaw(state.chartsData)
      const historyData = externalParams.historyData ? externalParams.historyData : toRaw(state.historyData)
      const chartsData = !isEmpty(dataMachines) ? dataMachines.filter((machine) => machine.machine_id !== null) : []
      const chartsMountData =  !isEmpty(dataMount) ? dataMount.filter((el) => el.client_type !== null) : []

      const updatedData = loadingChartsData({chartsSetup: chartsSetup, data: chartsData, dataMount: chartsMountData, prevGroupByData: {}, prevGroupByFilters: {}})
      const filteredSelects = prepareSelects(selects, selectors)
      const mergedData = mergedMachines(dataMachines, historyData)
      const currentTableData = loadingPagination(dataMachines, pagination)
      const currentSelectedMode = externalParams.urlParams ? externalParams.urlParams : 'cards'
      // console.log('updatedData', updatedData)
      
      commit('setSelectedMode', currentSelectedMode)
      commit('setTableData', currentTableData)
      commit('setPagination', pagination)
      commit('setSelectsData', filteredSelects)
      commit('setChartsData', updatedData)
      commit('setChartsDataMount', chartsMountData)
      commit('setMachinesDataDefault', dataMachines)
      commit('setMachinesData', mergedData)
    } catch (err) {
      console.error(err)
    }
  },
  updateSearch: async ({commit, getters, state}, updatedSearchValue) => {
    try {
      const selectedSearchMode = toRaw(getters.selectedSearchMode)
      const selectedData = toRaw(getters.selectedData)
      const machinesDataDefault = toRaw(state.machinesDataDefault)
      // const machinesData = toRaw(state.machinesData)
      const isEmptyParams = isEmpty(selectedData)
      let updatedFilters = []
      if (updatedSearchValue) {
        console.log('isEmptyParams', isEmptyParams)
        console.log('selectedData', selectedData)
        // updatedFilters = isEmptyParams ? [{[selectedSearchMode.key]: updatedSearchValue}] : [...selectedData.filter, {[selectedSearchMode.key]: updatedSearchValue}]
        updatedFilters = [{[selectedSearchMode.key]: updatedSearchValue}] 
      }
      if (!updatedSearchValue) {
        updatedFilters = !isEmptyParams ? selectedData.filter.filter((el) => !el[selectedSearchMode.key]) : selectedData
      }
      const updatedFiltersForSend = {filter: updatedFilters}
      // const currentData = !isEmptyParams && updatedSearchValue && !isEmpty(machinesData) ? machinesData : machinesDataDefault
      const updatedData = setUpdatedDataMachines(machinesDataDefault, updatedFiltersForSend)
      const updatedDataCharts = loadingChartsData({chartsSetup: chartsSetup, data: updatedData, dataMount: dataMount, prevGroupByData: {}, prevGroupByFilters: {}})
      commit('setSelectedData', updatedFiltersForSend)
      commit('setSelectedSelects', {})
      commit('setSearchValue', updatedSearchValue)
      commit('setMachinesData', updatedData)
      commit('setChartsData', updatedDataCharts)
      colorSelection(selectedSearchMode.key, updatedSearchValue)
      // console.log('updatedFilters', updatedFilters)
      // console.log('updatedData', updatedData)
    } catch (err) {
      console.error(err)
    }
  },
  updateSelects: async ({dispatch, commit, getters, state}, updatedSelect) => {
    try {
      const allSelects = toRaw(getters.selectsData)
      const selectedSelects = toRaw(getters.selectedSelects)
      const machinesDataDefault = toRaw(state.machinesDataDefault)
      dispatch('updateSearch', '')
      const curUpdatedSelectName = updatedSelect.key === 'set' ? updatedSelect.value[0].name : updatedSelect.value.name
      let updatedSelects = {}
      for (let i = 0; i < allSelects.length; i++) {
        const curSelect = allSelects[i]
        const newSelected = curSelect.data.find((el) => el.name === curUpdatedSelectName)
        if (!newSelected && (selectedSelects[curSelect.key] && selectedSelects[curSelect.key].length > 0)) {
          updatedSelects[curSelect.key] = selectedSelects[curSelect.key]
        }
        if (updatedSelect.key === 'removed' && newSelected && (selectedSelects[curSelect.key] && selectedSelects[curSelect.key].length === 0)) {
          break
        }
        if (updatedSelect.key === 'removed' && newSelected && (selectedSelects[curSelect.key] && selectedSelects[curSelect.key].length > 0)) {
            updatedSelects[curSelect.key] = selectedSelects[curSelect.key].filter((el) => el.name !== newSelected.name)
          break
        } 
        if (updatedSelect.key === 'set' && newSelected && (selectedSelects[curSelect.key] && selectedSelects[curSelect.key].length > 0)) {
          updatedSelects[curSelect.key] = selectedSelects[curSelect.key]
          break
        }
      }
      const updatedFilters = Object.entries(updatedSelects).map(([key, value]) => ({[key]: value.map((el) => el.name)}))
      // const mergedFilters = searchValue ? [...updatedFilters, {[selectedSearchMode.key]: searchValue}] : updatedFilters
      // console.log('mergedFilters', mergedFilters)
      // const currentData = !isEmptyParams ? machinesData : machinesDataDefault
      const updatedFiltersForSend = {filter: updatedFilters}
      const updatedData = setUpdatedDataMachines(machinesDataDefault, updatedFiltersForSend)
      const updatedDataCharts = loadingChartsData({chartsSetup: chartsSetup, data: updatedData, dataMount: dataMount, prevGroupByData: {}, prevGroupByFilters: {}})
      // console.log('updatedData', updatedData)
      // console.log('updatedFilters', updatedFilters)
      commit('setMachinesData', updatedData)
      commit('setChartsData', updatedDataCharts)
      commit('setSelectedSelects', updatedSelects)
      commit('setSelectedData', updatedFiltersForSend)
    } catch (err) {
      console.error(err)
    }
  },
  updateCharts: async ({commit, getters, state}, updatedData) => {
    try {
      switch(updatedData.action) {
        case 'nextLayoutChart':
          // console.log('updatedDataNext', updatedData)
          const prevGroupByFiltersNext = updatedData.prevGroupByFilters
          const updatedFiltersNext = {...prevGroupByFiltersNext, ...updatedData.prevGroupByData}
          const prevGroupByValue = updatedData.prevGroupByData.type ? updatedData.prevGroupByData.type : null
          const groupByKeyNext = setNextLayoutGroupByKey(updatedData.groupByKey, prevGroupByValue)
          if (groupByKeyNext) {
            const activeChartData = {id: updatedData.id, data: updatedData.data, groupByKey: groupByKeyNext, filterKey: updatedData.filterKey, type: updatedData.type, groupByValue: updatedData.groupByValue}
            const newData = setBarTypesChart(activeChartData, updatedData.prevGroupByData, updatedFiltersNext, state.machinesDataDefault, toRaw(state.chartsData))
            return commit('setActiveChartData', {...activeChartData, data: newData})
          }
          break
        case 'beforeLayoutChart':
          // console.log('updatedDataBefore', updatedData)
          const prevGroupByData = updatedData.groupByInfo.prevGroupByData
          const prevGroupByFiltersBefore = updatedData.groupByInfo.prevGroupByFilters
          const groupByKeyBefore = Object.keys(prevGroupByData)[0] // Получаем уже предыдущее значение ключа
          delete prevGroupByFiltersBefore[groupByKeyBefore] // Удаляем значение после вычисления prevGroupByData, так как подымаемся на уровень выше, сохраняя актуальное значение для фильтрации
          const isOnlyFiltersParams = equals(prevGroupByData, prevGroupByFiltersBefore)
          const updatedPrevGroupByDataBefore = isOnlyFiltersParams ? {} : setBeforeLayoutGroupByData(prevGroupByData, prevGroupByFiltersBefore, updatedData.groupByInfo.type)
          if (groupByKeyBefore) {
            const activeChartData = {id: updatedData.id, data: updatedData.data, groupByKey: groupByKeyBefore, filterKey: updatedData.filterKey, type: updatedData.groupByInfo.type, groupByValue: updatedData.groupByInfo.groupByValue}
            const newData = setBarTypesChart(activeChartData, updatedPrevGroupByDataBefore, prevGroupByFiltersBefore, state.machinesDataDefault, toRaw(state.chartsData))
            return commit('setActiveChartData', {...activeChartData, data: newData})
          }
          break
        case 'openMenuChart':
          // console.log('updatedDataOpen', updatedData)
          const openMenuChart = toRaw(state.activeMenuChartData.openMenuChart)
          updatedData.groupByInfo.data[0].type = updatedData.groupByInfo.type
          const activeChartDataMenu = {chartId: updatedData.groupByInfo.chartId, data: updatedData.groupByInfo.data, groupByKey: updatedData.groupByInfo.groupByKey, filterKey: updatedData.groupByInfo.filterKey, type: updatedData.groupByInfo.type, groupByValue: updatedData.groupByInfo.groupByValue}
          const newDataMenu = setBarTypesChart(activeChartDataMenu, updatedData.groupByInfo.prevGroupByData, updatedData.groupByInfo.prevGroupByFilters, state.machinesDataDefault, toRaw(state.chartsData))
          const isNotTypesChartsMenu = typesCharts(updatedData.groupByInfo.type)
          const toggleActiveMenuChartData = {openMenuChart: !openMenuChart, groupByInfo: {...activeChartDataMenu, data: isNotTypesChartsMenu ?  updatedData.groupByInfo.data[0] : newDataMenu}}
          commit('setActiveMenuChartData', toggleActiveMenuChartData)
          break
        case 'downloadChart':
          // console.log('updatedDataDownload', updatedData)
          const activeChartDataDownload = {chartId: updatedData.groupByInfo.chartId, isDownloadChart: updatedData.groupByInfo.isDownloadChart, data: updatedData.groupByInfo.data, groupByKey: updatedData.groupByInfo.groupByKey, prevGroupByData: updatedData.groupByInfo.prevGroupByData, prevGroupByFilters: updatedData.groupByInfo.prevGroupByFilters, filterKey: updatedData.groupByInfo.filterKey, type: updatedData.groupByInfo.type, groupByValue: updatedData.groupByInfo.groupByValue}
          const newDataDownload = setBarTypesChart(activeChartDataDownload, updatedData.groupByInfo.prevGroupByData, updatedData.groupByInfo.prevGroupByFilters, state.machinesDataDefault, toRaw(state.chartsData))
          const isNotTypesChartsDownload = typesCharts(updatedData.groupByInfo.type)
          const downloadActiveMenuChartData = {openMenuChart: false, groupByInfo: {...updatedData.groupByInfo, data: isNotTypesChartsDownload ?  updatedData.groupByInfo.data[0] : newDataDownload}}
          commit('setActiveMenuChartData', downloadActiveMenuChartData)
          break
        case 'legendFiltersParams':
          commit('setLegendFiltersParams', updatedData.data)
        default: return false
      }
    } catch (err) {
      console.error(err)
    }
  },
  updatePagination: async ({commit, getters, state}, updatedData) => {
    try {
      const pagination = toRaw(getters.pagination)
      const machinesDataDefault = toRaw(state.machinesDataDefault)
      const newData = setPagination(machinesDataDefault, pagination, updatedData)
      console.log('currentTableData', newData.currentTableData)
      commit('setTableData', newData.currentTableData)
      commit('setPagination', newData.updatedPagination)
    } catch (err) {
      console.error(err)
    }
  },
  openMapModal: async ({commit, state}, machine) => {
    try {
      // Добавить запрос на получение координат
      /*
        machine_id = machine["machine_id"]
        last_loc = Communicator.PackFetcher.last_locations([machine_id])
        
      */
      const coords = [44.510345, 48.771025]
      const params = {machine: machine, coords: coords}
      commit('setMapData', params)
    } catch (err) {
      console.error(err)
    }
  },
  openDataModal: async ({commit, state}, machine) => {
    try {

      // Добавить запрос на получение пакетов и информации о машине
      /*
        curr_machine_info = Communicator.Devices.askr_devices(where: "imei = #{imei}")

      [{_, machine_name} | machine_info] =
        Analyzer.reparse_machine_info(curr_machine_info, :imei)
        |> Enum.reduce([], fn
          {"Текущая машина", _} = cur, acc -> [cur] ++ acc
          cur, acc -> acc ++ [cur]
        end)

      report_packs =
        Enum.reduce(curr_machine_info, [], fn
          %{imei: imei}, acc ->
            acc ++
              PacksFuncs.get_pack_nums(
                imei,
                Timex.now() |> Timex.beginning_of_day(),
                Timex.now() |> Timex.end_of_day()
              )

          _, acc ->
            acc
        end)
        |> DynamicStructDestroyer.destroy()
        |> Enum.sort_by(& &1.packNumber)
          
        */

      commit('setMachineInfo', machineInfo)
      commit('setReportPacks', reportPacks)
    } catch (err) {
      console.error(err)
    }
  },
  loadPack: async ({commit, state}, packNumber) => {
    try {

      /* Получение данных о пакете
        report =
      Enum.reduce(curr_machine_info, [], fn
        %{imei: imei}, acc ->
          acc ++ PacksFuncs.upload_machine_data(imei, pack_number, dt_start, dt_finish, 30) // Огреничение до 30 машин askr_logs

        _, acc ->
          acc
      end)
      |> DynamicStructDestroyer.destroy()

      Получение структуры пакета

      pack_structs = Helper.get_structs_of_pack(pack_number)

      def get_structs_of_pack(pack_number) do
        LiveMonitor.Packages.list_pack_struct()
        |> Enum.filter(&(&1.pack == pack_number))
      end

      */
      console.log('packNumber', packNumber)
      // const dataSource = !isEmpty(report) ? report.askr_logs.sort((a, b) => b.pack_dt - a.pack_dt) : []
      const dataSource = !isEmpty(multiReport) ? multiReport.askr_logs.sort((a, b) => b.pack_dt - a.pack_dt).slice(0, 30) : []  // Огреничение до 30 машин askr_logs
      // const columns = fetchColumn(packStructure, report)
      const columns = fetchColumn(multiPackStructure, multiReport)
      // const selectedPackStruct = packStructure.map((item) => ({id: item.id, name: item.name, packNumber: packNumber}))
      console.log('multiPackStructure', multiPackStructure)
      console.log('multiReport', multiReport)
      console.log('columns', columns)
      const selectPackStructs = multiPackStructure.map((item) => ({id: item.id, name: item.name, packNumber: packNumber}))
      commit('setStructPackDefault', multiPackStructure)
      commit('setSelectPackStructs', selectPackStructs)
      commit('setSelectedPackStruct', selectPackStructs[0])
      commit('setPackData', {dataSource, columns, height: '550px'})
      
    } catch (err) {
      console.error(err)
    }
  },
  updateModePack: async ({commit, getters, state}, updatedMode) => {
    try {
      const structPackDefault = toRaw(state.structPackDefault)
      const currentReport = multiReport[updatedMode] ? multiReport[updatedMode] : []
      const columns = updatedMode === 'askr_logs' ? fetchColumn(structPackDefault, multiReport, null) : prepareSetPackColumns(updatedMode, currentReport)
      console.log('columns', columns)
      console.log('currentReport', currentReport)
      commit('setSelectedPackMode', updatedMode)
      commit('setPackData', {dataSource: currentReport, columns, height: '550px'})
    } catch (err) {
      console.error(err)
    }
  },
  updateSelectStruct: async ({commit, getters, state}, updatedStructId) => {
    try {
      const updatedMode = toRaw(getters.selectedPackMode)
      const currentReport = toRaw(state.packData.dataSource)
      const structPackDefault = toRaw(state.structPackDefault)
      const selectPackStructs = toRaw(getters.selectPackStructs)
      const [selectedPackStruct] = selectPackStructs.filter((item) => item.id === updatedStructId)
      console.log('selectedPackStruct', selectedPackStruct)
      // const currentReport = multiReport[updatedMode] ? multiReport[updatedMode] : []
      const columns = updatedMode === 'askr_logs' ? fetchColumn(structPackDefault, multiReport, updatedStructId) : prepareSetPackColumns(updatedMode, currentReport)
      console.log('updatedMode', updatedMode)
      console.log('structPackDefault', structPackDefault)
      console.log('columns', columns)
      console.log('currentReport', currentReport)
      commit('setSelectedPackStruct', selectedPackStruct)
      commit('setPackData', {dataSource: currentReport, columns, height: '550px'})
    } catch (err) {
      console.error(err)
    }
  },
  clearFilters: async ({commit, state}) => {
    try {
      const machinesDataDefault = toRaw(state.machinesDataDefault)
      const updatedFiltersForSend = {filter: []}
      const updatedData = setUpdatedDataMachines(machinesDataDefault, updatedFiltersForSend)
      const updatedDataCharts = loadingChartsData({chartsSetup: chartsSetup, data: updatedData, dataMount: dataMount, prevGroupByData: {}, prevGroupByFilters: {}})
      commit('setSelectedSelects', {})
      commit('setSelectedData', [])
      commit('setMachinesData', updatedData)
      commit('setChartsData', updatedDataCharts)
    } catch (err) {
      console.error(err)
    }
  },
  resetStore: ({commit}) => {
    commit('resetStore')
  }
};

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