import {groupByKeys} from './staticData'

const getTextWidth = (text, font) => {
     const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement('canvas'));
     const context = canvas.getContext('2d');
     context.font = font;
     const metrics = context.measureText(text);
     return metrics.width;
}

const isEqualKeyValue = (obj, key, value) => {
     if(Object.keys(obj).length > 0) {
          if(Object.keys(obj).includes(key) && Object.values(obj).includes(value)) return true
               else return false
     } else return true
}

const chartsFiltersNames = (data) => [...new Set(data.map((el) => el.charts.map((item) => item.name)).flat())]
const chartsFiltersNamesMl = (data) => [...new Set(data.map((el) => el.map((item) => item.charts.name)).flat().filter(el => el !== undefined))]

const updateBarChartsData = (data, key) => data.map((el) => {
          return el.filter((item) => {
          if(item.name === key) {
               return el
          }
     })
}).flat()

const dataFilterTitle = (data, title) => data.map((el) => {
     return el.reduce((acc, item) => {
          if(item.name === title || acc !== undefined && acc?.name === title) {
               if(acc === 0) {
                    return {name: item.name, count: Number(item.value)}
               }
               if(acc?.count >= 0) {
                    return {name: item.name, count: acc.count + Number(item.value)}
               }
          }
     }, 0)
}).filter((el) => el !== undefined)

const prepareBarTypesData = (data, xAxisData, params) => {
     if(data.charts.length < chartsFiltersNames(xAxisData).length) {
          // Если нет фильтруемых данных, то добавляем столбец графика с нулевым значением для каждого элемента el
          const zeroData = chartsFiltersNames(xAxisData).filter((name) => !data.charts.some(({name: name2}) => name === name2)).map((name) => {
               return {filterKey: params.filterKey, name: name, value: 0}
          })
          const withoutZeroData = data.charts.map((item) => {
               item.type = params.type
               item.filterKey = params.filterKey
               item.groupByKey = params.groupByKey
               item.groupByValue = params.groupByValue ? params.groupByValue : params.typeId // Для графика типа "types" params.typeId
               item.groupByData = {[params.groupByKey]: data.yAxisData}
               item.prevGroupByData = params.prevGroupByFilters
               return item})
             return [withoutZeroData, zeroData].flat()
     } else {
          return data.charts.map((item) => {
               item.type = params.type
               item.filterKey = params.filterKey
               item.groupByKey = params.groupByKey
               item.groupByValue = params.groupByValue ? params.groupByValue : params.typeId
               item.groupByData = {[params.groupByKey]: data.yAxisData}
               item.prevGroupByData = params.prevGroupByFilters
               return item
          })
     }
}

const prepareBarTypesMlData = (data, params) => {
     return data.map((item) => {
          // console.log('item', item)
          item.charts.type = params.type
          item.charts.groupByKey = params.groupByKey
          item.charts.groupByValue = params.groupByValue ? params.groupByValue : params.typeId
          item.charts.groupByData = {[params.groupByKey]: item.yAxisData}
          item.charts.prevGroupByData = params.prevGroupByFilters
          return item.charts
     })
}

const groupByBarTypesData = (data, xAxisData, func) => {
     const dataGroupBy = []
     const dataCustomTitle = []

     for(let i = 0; i < (func(xAxisData).length); i++) {
          dataGroupBy.push(updateBarChartsData(data, func(xAxisData)[i]))
          dataCustomTitle.push(dataFilterTitle(dataGroupBy, func(xAxisData)[i]))
     }

     return {dataGroupBy: dataGroupBy, dataCustomTitle: dataCustomTitle}
}

const updatedGroupByData = (idx, prevGroupByFilters, groupByKey, groupByValue) => {

     switch(idx) {
          case '0': return {[groupByKey]: groupByValue}
          case '1': 
               for (const prevGroupByFilter in prevGroupByFilters) {
                    if(prevGroupByFilter === groupByKeys.secondLayout) {
                         delete prevGroupByFilters[prevGroupByFilter]
                    }
                    if(prevGroupByFilter === groupByKeys.thirdLayout) {
                         delete prevGroupByFilters[prevGroupByFilter]
                    }
                    if(prevGroupByFilter === groupByKeys.fourthLayout) {
                         delete prevGroupByFilters[prevGroupByFilter]
                    }
               }
               return prevGroupByFilters
          case '2':
               for (const prevGroupByFilter in prevGroupByFilters) {
                    if(prevGroupByFilter === groupByKeys.thirdLayout) {
                         delete prevGroupByFilters[prevGroupByFilter]
                    }     
                    if(prevGroupByFilter === groupByKeys.fourthLayout) {
                         delete prevGroupByFilters[prevGroupByFilter]
                    }
               }
               return prevGroupByFilters
          case '3':
               for (const prevGroupByFilter in prevGroupByFilters) {
                    if(prevGroupByFilter === groupByKeys.fourthLayout) {
                         delete prevGroupByFilters[prevGroupByFilter]
                    }
               }
               return prevGroupByFilters
     }

}

const choiceTypeBarTypesCharts = (params) => {
     switch(params.type) {
          case 'ml':
               const yAxisMlData = params.yAxisData.sort().map((el) => {
                    return `${el.key !== null ? el.key : 'Нет данных'} ${el.val}`
               }).sort((a, b) => a - b).reverse()
               const xAxisMlData = params.xAxisData.map((item) => item.map((el) => el))
               const mlData = xAxisMlData.sort().map((el) => prepareBarTypesMlData(el, params))
               return {axisData: yAxisMlData, updatedData: groupByBarTypesData(mlData, xAxisMlData, chartsFiltersNamesMl)}

          case 'mount':
               const xAxisMountData = params.yAxisData.sort((a, b) => a.key - b.key).map((el) => {
                    return `${el.key !== null ? el.key : 'Нет данных'} \n ${el.val}`})
               const mountData = params.xAxisData.sort().map((el) =>  prepareBarTypesData(el, params.xAxisData, params))
               return {axisData: xAxisMountData, updatedData: groupByBarTypesData(mountData, params.xAxisData, chartsFiltersNames)}

          default :
               const yAxisDefaultData = params.yAxisData.sort().map((el) => {
                    return `${el.key !== null ? el.key : 'Нет данных'} ${el.val}`
               }).sort((a, b) => a - b).reverse()
               const defaultData = params.xAxisData.sort().map((el) => prepareBarTypesData(el, params.xAxisData, params))
                    return {axisData: yAxisDefaultData, updatedData: groupByBarTypesData(defaultData, params.xAxisData, chartsFiltersNames)}
     }
}

export {isEqualKeyValue, getTextWidth, updatedGroupByData, choiceTypeBarTypesCharts}