import type { PropType } from 'vue';
import { defineComponent, ref, watch, toRef, onMounted, onBeforeUnmount, toRefs, computed, inject, onUnmounted, nextTick } from 'vue'
import { useI18n } from 'vue-i18n'

import { tools } from '../../store/Modules/tools'

import { fieldsTable } from '@store/Modules/fieldsTable'

import { shared_consts } from '@src/common/shared_vuejs'

import type {
  IColGridTable,
  IFilter,
  ITableRec,
  ISearchList,
  IPagination,
  IParamDialog,
  IMySkill,
  IOptGrid
} from 'model';
import {
  ICoordLatLng,
  ICoordGPS
} from 'model'
import { lists } from '@store/Modules/lists'
import type { IParamsQuery } from 'model'
import { CMyPopupEdit } from '../CMyPopupEdit'
import { CMyFriends } from '../CMyFriends'
import { CNotifSettings } from '../CNotifSettings'
import { CMyUser } from '../CMyUser'
import { CMyGroups } from '../CMyGroups'
import { CMyFieldDb } from '../CMyFieldDb'
import { CMyRecCard } from '../CMyRecCard'
import { CMyRecCatalog } from '../CMyRecCatalog'
import { CMapByTable } from '../CMapByTable'
import { CMyRecGrpCard } from '../CMyRecGrpCard'
import { CMyRecCircuitCard } from '../CMyRecCircuitCard'
import { CMySelect } from '../CMySelect'
import { CTitleBanner } from '../CTitleBanner'

import { useUserStore } from '@store/UserStore'
import { useGlobalStore } from '@store/globalStore'
import { useQuasar, exportFile } from 'quasar'
import { costanti } from '@costanti'
import translate from '@src/globalroutines/util'
import { toolsext } from '@store/Modules/toolsext'
import { CMyCardPopup } from '@src/components/CMyCardPopup'
import { CMyCardService } from '@src/components/CMyCardService'
import { CSingleMovement } from '@src/components/CSingleMovement'
import { CMyCardGrpPopup } from '@src/components/CMyCardGrpPopup'
import { CMyCardCircuitPopup } from '@src/components/CMyCardCircuitPopup'
import { onBeforeRouteLeave, onBeforeRouteUpdate, useRouter } from 'vue-router'
import { useRoute } from 'vue-router'
import { NavigationGuardNext, RouteLocationNormalized } from 'vue-router'

import { Dialog } from 'quasar'; // Assicurati di importare correttamente Dialog da Quasar.

import { getMapBoundaries } from '@src/store/Modules/geocodingmap'
import { isMap } from 'util/types'

export default defineComponent({
  name: 'CGridTableRec',
  emits: ['clickButtBar', 'savefilter'],
  props: {
    prop_mytitle: {
      type: String,
      required: true,
    },
    prop_mytitlenew: {
      type: String,
      required: false,
      default: '',
    },
    subtitle: {
      type: String,
      required: false,
      default: '',
    },
    prop_mytable: {
      type: String,
      required: false,
      default: '',
    },
    prop_mycolumns: {
      type: Object as PropType<any[]>,
      required: false,
      default: null,
    },
    prop_colkey: {
      type: String,
      required: false,
      default: '',
    },
    prop_showfilter: {
      type: Boolean,
      required: false,
      default: false,
    },
    hintinbtnsearch: {
      type: Boolean,
      required: false,
      default: false,
    },
    findByDebounce: {
      type: Boolean,
      required: false,
      default: false,
    },
    showSearchOnTop: {
      type: Boolean,
      required: false,
      default: false,
    },
    hint: {
      type: String,
      required: false,
      default: 'Cerca',
    },
    prop_search: {
      type: Boolean,
      required: false,
      default: true,
    },
    butt_modif_new: {
      type: Boolean,
      required: false,
      default: true,
    },
    finder: {
      type: Boolean,
      required: false,
      default: false,
    },
    visuinpage: {
      type: Boolean,
      required: false,
      default: false,
    },
    showType: {
      type: Number,
      required: false,
      default: 0,
    },
    enableExport: {
      type: Boolean,
      required: false,
      default: false,
    },
    finder_noNull: {
      type: Boolean,
      required: false,
      default: false,
    },
    finder_noNullFilters: {
      type: Boolean,
      required: false,
      default: false,
    },
    vertical: {
      type: Number,
      required: false,
      default: 0,
    },
    prop_codeId: {
      type: String,
      required: false,
      default: '',
    },
    actionType: {
      type: Number,
      required: false,
      default: 0,
    },
    /*    keyMain: {
          type: String,
          required: false,
          default: '',
        },

     */
    nodataLabel: {
      type: String,
      required: false,
      default: '',
    },
    labelBtnAddRow: {
      type: String,
      required: false,
      default: 'Aggiungi',
    },
    labelBtnAddExtra: {
      type: String,
      required: false,
      default: 'Aggiungi',
    },
    noresultLabel: {
      type: String,
      required: false,
      default: '',
    },
    tablesList: {
      type: Object as PropType<ITableRec[]>,
      required: false,
      default: null,
    },
    prop_searchList: {
      type: Object as PropType<ISearchList[]>,
      required: false,
      default: null,
    },
    arrfilters: {
      type: Object as PropType<IFilter[]>,
      required: false,
      default: null,
    },
    opt: {
      type: Object as PropType<IOptGrid>,
      required: false,
      default: () => {
        return {}
      },
    },
    filterdef: {
      type: Array,
      required: false,
      default: () => {
        return []
      }
    },
    filtercustom: {
      type: Array,
      required: false,
      default: () => {
        return []
      }
    },
    filterextra: {
      type: Array,
      required: false,
      default: () => {
        return []
      }
    },
    filterextra2: {
      type: Array,
      required: false,
      default: () => {
        return []
      }
    },
    extraparams: {
      required: false,
      default: {},
    },
    options: {
      required: false,
      default: 0,
    },
    heightcarousel: {
      type: String,
      required: false,
      default: '',
    },
    prop_pagination: {
      type: Object as PropType<IPagination>,
      required: false,
      default: () => {
        return { sortBy: 'desc', descending: false, page: 1, rowsNumber: 0, rowsPerPage: 10 }
      },
    },
    prop_SortFieldsAvailable: {
      type: Array,
      required: false,
      default: () => {
        return []
      },
    },
    margin_right: {
      type: Number,
      required: false,
      default: 0,
    },
    defaultnewrec: {
      type: Object,
      required: false,
      default: () => {
        return {}
      },
    },
    col_title: {
      type: String,
      required: false,
      default: '',
    },
    col_footer: {
      type: String,
      required: false,
      default: '',
    },
    col_tabfooter: {
      type: String,
      required: false,
      default: '',
    },
    showCol: {
      type: Boolean,
      required: false,
      default: true
    },
    showHeaderCol: {
      type: Boolean,
      required: false,
      default: false
    },
    choose_visutype: {
      type: Boolean,
      required: false,
      default: false
    },
    visufind: {
      type: Number,
      required: false,
      default: costanti.FIND_PEOPLE,
    },
    extrafield: {
      type: String,
      required: false,
      default: '',
    },
    circuitname: {
      type: String,
      required: false,
      default: '',
    },
    noaut: {
      type: Boolean,
      required: false,
      default: false,
    },
    hidetitleIfEmpty: {
      type: Boolean,
      required: false,
      default: false,
    },
    labelElemFind: {
      type: String,
      required: false,
      default: 'elementi trovati',
    },
    groupname: {
      type: String,
      required: false,
      default: '',
    },
    prop_showMap: {
      type: Boolean,
      required: false,
      default: false,
    }
  },
  components: {
    CMyPopupEdit, CTitleBanner, CMyFieldDb, CMySelect, CMyFriends, CMyGroups,
    CMyUser, CMyRecCard, CMyRecCatalog, CMyCardPopup, CMyRecGrpCard, CMyCardGrpPopup, CMyCardCircuitPopup,
    CMyRecCircuitCard, CMyCardService, CNotifSettings, CMapByTable, CSingleMovement,
  },
  setup(props, { emit }) {
    const $q = useQuasar()
    const router = useRouter()
    const route = useRoute()

    const { t } = useI18n()
    const userStore = useUserStore()
    const globalStore = useGlobalStore()
    const isfinishLoading = computed(() => globalStore.finishLoading)

    const pagination = ref({ sortBy: 'desc', descending: false, page: 1, rowsNumber: 0, rowsPerPage: 10 } as IPagination)

    const addRow = ref('Aggiungi')
    const actmonth = ref('')
    const drawmonth = ref(true)

    const page = ref(0)

    const showMap = ref(false)
    const showMapAtLeast1 = ref(false)
    const mapInitialized = ref(false)
    const slideGridOriz = ref(0)
    const autoplay = ref(false)
    const autoplayInterval = ref(<any>null)

    const scrollTargetId = 'carousel-scroll-target'

    const newRecordBool = ref(false)
    const editRecordBool = ref(false)
    const newRecord = ref(<any>{})
    const recSaved = ref(<any>{})
    const recModif = ref(<any>{})
    const showInnerDialog = ref(false)

    const carouselTabRef = ref(<any>null)
    const isAtStart = ref(true)
    const isAtEnd = ref(false)
    const activeIndex = ref(0)
    const addEventScroll = ref(false)

    const mytable = ref('')
    const mytitle = ref('')
    const mytitlenew = ref('')
    const mycolumns = ref([] as any[])
    const colkey = ref('')
    const search = ref('')
    const showSearchDialog = ref(false)
    const myMapComp = ref(<any>null)

    const tablesel = ref('')
    const showfilteradv = ref(false)
    const showSpin = ref(false)
    const showNotification = ref(false)

    // const withdate = computed(() => shared_consts.TABLES_WITH_DATE.includes(tablesel.value))
    const withdate = ref(false)

    const loading = ref(false)
    const alreadymounting = ref(false)
    const editOn = computed({
      get: () => globalStore.editOn,
      set: val => {
        tools.updateEditOn(val)
      },
    })

    const boundariesMap = ref({ ne: 0, sw: 0 } as any)
    const precboundariesMap = ref({ ne: 0, sw: 0 } as any)

    const visupagedialog = ref(false)
    const myrecdialog = ref(null)
    const myIdRecDialog = ref(null)

    const startsearch = ref(false)
    const clickbuttsearch = ref(false)

    const myinfscroll = ref(null)

    const serverData: any = ref([] as any[])
    const numRecLoaded = ref(0)
    const spinner_visible = ref(false)
    const changetable = ref(false)
    const searchList = ref([] as ISearchList[])

    const actual = ref(<any>'')

    let idsel = ''
    const colsel = ref({ name: '', field: '', sortable: false } as IColGridTable | null)
    let valPrec = ''

    const separator = 'horizontal'
    const myfilter = ref('')
    const myfilterand: any = ref([])
    const rowsel: any = ref({})
    const dark = true
    const canEdit = ref(false)

    const returnedData: any = ref([])
    let returnedCount = 0
    const colVisib: any = ref([])
    const colNotVisib: any = ref([])
    const colExtra: any = ref([])
    const actualDate: any = ref(null as any)

    const rowclicksel = ref(null as any)
    const colclicksel = ref(null)

    const selected: any = ref([])
    const showfilter = ref(false)  // filtri avanzati

    const filter = ref(0)
    const filtergrp = ref(costanti.MY_GROUPS)

    const mycodeid = toRef(props, 'prop_codeId')

    const myvertical = ref(props.vertical)

    const ordinam = ref('')
    const ordinam_desc = ref(false)

    const autoaggiornaMappaSeMuovi = ref(true)

    /*onBeforeRouteUpdate((to: any, from: any, next: any) => {
      console.log('onBeforeRouteUpdate', 'to', to, 'from', from, 'next', next)
      next()
    })*/

    onBeforeRouteLeave((to: any, from: any, next: any) => {
      // console.log('onBeforeRouteLeave', 'to', to, 'from', from, 'next', next)
      if ((editRecordBool.value || newRecordBool.value) && checkForChanges()) {
        const answer = window.confirm(t('dialog.uscire'))
        if (answer) {
          next()
        } else {
          next(false)
        }
      } else {
        next()
      }
    })

    // Funzione per simulare il controllo delle modifiche
    const checkForChanges = (): boolean => {
      // Funzione di utilità per confrontare due valori
      const isEqual = (val1: any, val2: any): boolean => {
        if (typeof val1 !== typeof val2) return false
        if (typeof val1 === 'object' && val1 !== null && val2 !== null) {
          const keys1 = Object.keys(val1)
          const keys2 = Object.keys(val2)
          if (keys1.length !== keys2.length) return false
          return keys1.every(key => isEqual(val1[key], val2[key]))
        }
        return val1 === val2
      }

      // Confronta recModif con recSaved
      return !isEqual(recModif.value, recSaved.value)
      // return true
    }

    function saveChanges() {
      if (editRecordBool.value) {
        saverecModif()
      }
      if (newRecordBool.value) {
        saveNewRecord()
      }

    }
    const getNumRecFromQuery = computed(() => () => {
      return serverData.value.length
    })
    const valoriopt = computed(() => (item: any, addall?: boolean, addnone?: boolean) => {
      // console.log('valoriopt', item.table)
      return globalStore.getTableJoinByName(item.table, addall, addnone, item.filter)
    })
    const lengthopt = computed(() => (item: any, addall: boolean, addnone?: boolean) => {
      // console.log('valoriopt', item.table)
      const valori = globalStore.getTableJoinByName(item.table, addall, addnone, item.filter)
      return (valori ? valori.length : 0)
    })

    const labelcombo = computed(() => (item: any) => {
      let lab = item.label
      if (item.showcount)
        lab += ' (' + valoriopt.value(item, false, false).length + ')'
      return lab
    })

    watch(() => globalStore.addNewRecord, (value: any, oldval: any) => {
      if (globalStore.addNewRecord === props.prop_mytable) {
        createNewRecordDialog()
        globalStore.addNewRecord = ''
      }
    })

    watch(() => globalStore.myselector, (value: any, oldval: any) => {
      // console.log('******* CGRIDTABLEREC : globalStore.myselector', globalStore.myselector)
      // console.log(' .  value', value)
      const rec = searchList.value.find((myrec) => myrec.table === globalStore.myselector.table) // check if exist
      if (rec) {
        rec.value = globalStore.myselector.data

        // Reset others tables
        const rec2 = searchList.value.find((myrec) => myrec.table === toolsext.TABREGIONS) // check if exist
        if (rec2) {
          rec2.value = costanti.FILTER_TUTTI
        }
        const rec3 = searchList.value.find((myrec) => myrec.table === toolsext.TABPROVINCE) // check if exist
        if (rec3) {
          rec3.value = costanti.FILTER_TUTTI
        }

      }

      if (value) {
        refresh()
      }
    },
    )


    watch(() => searchList.value, (to: any, from: any) => {
      // console.log('watch searchlist', to)
      if (searchList.value && !changetable.value) {
        console.log('REFRR searchList.value', to)
        refresh()
      }
    })
    watch(() => props.prop_mycolumns, (to: any, from: any) => {
      // console.log('watch searchlist', to)
      if (mycolumns.value !== props.prop_mycolumns) {
        mycolumns.value = props.prop_mycolumns
        refresh()
      }
    })

    watch(() => ordinam.value, (to: any, from: any) => {
      if (pagination.value.sortBy !== ordinam.value) {
        tools.setCookie('s_ordinamnew_' + props.prop_mytable, ordinam.value)
        // pagination.value.sortBy = getObjSort(ordinam.value, ordinam_desc.value)
        // refresh()
      }
    })

    watch(() => showfilter.value, (newval: any, from: any) => {
      tools.setCookie('s_adv', newval ? '1' : '0')
    })

    watch(() => props.filtercustom, (to: any, from: any) => {
      // console.log('filtercustom', to)
      if (JSON.stringify(to) !== JSON.stringify(from)) {
        // console.log('REFRR props.filtercustom', to, from)
        refresh()
      }
    })

    watch(() => props.extraparams, (to: any, from: any) => {
      // console.log('filtercustom', to)
      if (to !== from) {
        refresh()
      }
    })

    /* router.beforeResolve((to: any) => {
      console.log('beforeResolve', visupagedialog.value, 'to', to)

      if (visupagedialog.value && !to.meta.newpage) {
        // visupagedialog.value = false
        // return false
      }

    })*/

    function setCategBySector(tablecat: string, tabsector: string, newval: any) {
      console.log('setCategBySector', tablecat, tabsector, newval)

      const recSector = searchList.value.find((rec) => rec.table === tabsector)
      if (recSector)
        tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + tabsector, newval)

      for (const item of searchList.value) {
        if (item.table === tablecat) {
          const valsaved = tools.getCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + item.table + costanti.FILTER_SEP + newval, costanti.FILTER_TUTTI)
          const rec = searchList.value.find((myrec) => myrec.table === tablecat) // check if exist
          let trovato = false
          let arrvalues = []
          if (rec) {
            arrvalues = valoriopt.value(rec.value, false, false)
            if (arrvalues)
              trovato = arrvalues.find((myrec: any) => myrec[myrec.key] === valsaved)
          }
          console.log('   ...item', item)
          if (valsaved && trovato)
            item.value = valsaved
          else {
            if (arrvalues) {
              console.log('   ...filter tutti')
              item.value = costanti.FILTER_TUTTI
            }
          }
        }
      }

    }

    function setProvinceByRegion(tableprov: string, tabregion: string, newval: any) {

      const recRegion = searchList.value.find((rec) => rec.table === tabregion)
      if (recRegion)
        tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + tabregion, newval)

      for (const item of searchList.value) {
        if (item.table === tableprov) {
          const valsaved = tools.getCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + tableprov + costanti.FILTER_SEP + newval, costanti.FILTER_TUTTI)
          const rec = searchList.value.find((myrec) => myrec.table === tableprov) // check if exist
          let trovato = false
          let arrvalues = []
          if (rec) {
            arrvalues = valoriopt.value(rec.value, false, false)
            if (arrvalues)
              trovato = arrvalues.find((myrec: any) => myrec[myrec.key] === valsaved)
          }
          if (valsaved && trovato) {
            item.value = valsaved
            globalStore.myselector.data = item.value
          } else {
            if (arrvalues) {
              item.value = costanti.FILTER_TUTTI
            }
          }
        } else if (item.table === shared_consts.TAB_CITIES) {
          const valsaved = tools.getCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + item.table + costanti.FILTER_SEP + newval, costanti.FILTER_TUTTI)
          const rec = searchList.value.find((myrec) => myrec.table === shared_consts.TAB_CITIES) // check if exist
          let trovato = false
          let arrvalues = []
          if (rec) {
            arrvalues = valoriopt.value(rec.value, false, false)
            if (arrvalues)
              trovato = arrvalues.find((myrec: any) => myrec[myrec.key] === valsaved)
          }
          if (valsaved && trovato)
            item.value = valsaved
          else {
            if (arrvalues) {
              item.value = costanti.FILTER_TUTTI
            }
          }
          if (item.value === costanti.FILTER_TUTTI) {
            globalStore.myselector.data = { _id: 0, comune: '' }
          } else {
            globalStore.myselector.data = item.value
          }
        }
      }

    }

    function searchval(newval: any, table: any) {
      // console.log('REFRR searchval', newval, table, 'mytable', mytable.value)
      const myrecfilt = searchList.value.find((rec) => rec.table === table)
      let keycookie = tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + table
      if (myrecfilt && myrecfilt.keycookie)
        keycookie += myrecfilt.keycookie
      tools.setCookie(keycookie, newval)

      if (table === shared_consts.TABLES_MYSKILLS) {
        const recSector = searchList.value.find((rec) => rec.table === 'sectors')
        if (recSector) {
          tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + recSector.value, newval)
        }
      } else if (table === toolsext.TABSECTORS) {
        setCategBySector(shared_consts.TABLES_MYSKILLS, table, newval)
      } else if (table === toolsext.TABSECTORGOODS) {
        setCategBySector(toolsext.TABGOODS, table, newval)
      } else if (table === toolsext.TABREGIONS) {
        setProvinceByRegion(toolsext.TABPROVINCE, table, newval)
      } else if (table === toolsext.TABGOODS) {
        const recSector = searchList.value.find((rec) => rec.table === toolsext.TABSECTORGOODS)
        if (recSector) {
          tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + table + costanti.FILTER_SEP + recSector.value, newval)
        }
      } else if (table === shared_consts.TABLES_LISTA_EDITORI) {
        const rec = searchList.value.find((rec) => rec.table === table)
        if (rec) {
          tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + table + costanti.FILTER_SEP + 'referente', rec.value)
        }
        // setCategBySector('sectorgoods', table, newval)
      } else if (table === shared_consts.TAB_CITIES) {
        const rec = searchList.value.find((myrec) => myrec.table === shared_consts.TAB_CITIES) // check if exist
        if (rec) {
          if (rec.value === costanti.FILTER_TUTTI) {
            globalStore.myselector.data = { _id: 0, comune: '' }
          } else {
            globalStore.myselector.data = rec.value
          }
        }

      } else if (table === toolsext.TABPROVINCE) {
        const rec = searchList.value.find((myrec) => myrec.table === toolsext.TABPROVINCE) // check if exist
        if (rec) {
          globalStore.myselector.data = { _id: 0, comune: '' }
        }

      }


      refresh()
    }


    // emulate 'SELECT count(*) FROM ...WHERE...'
    function getRowsNumberCount() {

      // if (!myfilter) {
      //   return original.length
      // }
      // let count = 0
      // original.forEach((treat) => {
      //   if (treat['name'].includes(myfilter)) {
      //     ++count
      //   }
      // })
      // return count

      return returnedCount
    }

    function getOrderByField(field: string, precorder: number): number {
      if ((field === 'date_reg') || (field === 'numMembers')) {
        return -1;
      }
      if (field === 'namecomplete') {
        return 1;
      }

      return precorder ? precorder : 1;
    }

    function getObjSort(sortBy: any, descending: any) {
      const myobj: any = {}
      if (tools.isObject(sortBy)) {
        // console.log('sortBy', sortBy)
        return sortBy
      } else if (sortBy) {
        sortBy = sortBy + ''
        // descending = descending + ''
        const arrsort = (sortBy && sortBy.indexOf(',') > 0) ? sortBy.split(',') : [];
        const arrdescending = (descending && descending.length > 1 && descending.indexOf(',') > 0) ? descending.split(',') : [];
        if (arrsort.length > 0) {
          for (let i = 0; i < arrsort.length; i++) {
            const field = arrsort[i].trim()
            const risdesc = (tools.isArray(arrdescending) && (arrdescending.length > i)) ? parseInt(arrdescending[i].trim()) : 1;
            myobj[field] = getOrderByField(field, risdesc)
          }
        } else {
          myobj[sortBy] = getOrderByField(sortBy, descending ? -1 : 1)
        }
      }

      // console.log('myobj', myobj)
      return myobj
    }

    function getNumFilterSelected(): number {
      let numfilter = 0


      for (const item of searchList.value) {
        if (!item.notinsearch) {
          if (item.value && item.value !== -100) {
            // console.log(item.label, item.value)
            numfilter++
          }
        }
      }

      return numfilter
    }

    // emulate ajax call
    // SELECT * FROM ... WHERE...LIMIT...
    async function fetchFromServer(startRow: any, endRow: any, param_myfilter: any, param_myfilterand: any, sortBy: any, descending: any) {
      // console.log('fetchFromServer')

      // console.log('sortBy', sortBy)
      let myobj: any = {}
      if (tools.isObject(sortBy)) {
        myobj = sortBy
      } else if (tools.isArray(sortBy)) {
        myobj = getObjSort(sortBy, descending)
      } else if (sortBy) {
        myobj = {}
        if (descending) {
          myobj[sortBy] = -1
        } else {
          myobj[sortBy] = 1
        }
      }

      const filtersearch: any[] = []
      const filtersearch2: any[] = []
      const filtersearch3or: any[] = []
      const filtersearch3and: any[] = []
      const filtercustom: any[] = [...props.filtercustom]
      const filter_gte: any[] = []

      let recSector = null
      let recSectorGood = null
      let recCities = null
      let recRegion = null
      let recProvince = null
      let recSkill = null
      let idSector = 0
      let idSectorGood = 0
      let idProvince = 0
      let idRegion = 0
      let idSkill = 0
      if (searchList.value) {
        recSector = searchList.value.find((item: ISearchList) => item.table === toolsext.TABSECTORS)
        idSector = recSector ? recSector.value : 0
      }
      if (searchList.value) {
        recSectorGood = searchList.value.find((item: ISearchList) => item.table === 'sectorgoods')
        idSectorGood = recSectorGood ? recSectorGood.value : 0
      }
      if (searchList.value) {
        recProvince = searchList.value.find((item: ISearchList) => item.table === 'provinces')
        idProvince = recProvince ? recProvince.value : 0
      }
      if (searchList.value) {
        recRegion = searchList.value.find((item: ISearchList) => item.table === 'regions')
        idRegion = recRegion ? recRegion.value : 0
      }
      if (searchList.value) {
        recCities = searchList.value.find((item: ISearchList) => item.table === 'cities')
      }

      if (searchList.value) {
        recSkill = searchList.value.find((item: ISearchList) => item.table === shared_consts.TABLES_MYSKILLS)
        idSkill = recSkill ? recSkill.value : 0
        // console.log('recSkill', idSkill)
      }


      const arrfilter_cities: any = []
      const arrfilter_provices: any = []

      // console.table(searchList.value)

      if (searchList.value) {
        for (const item of searchList.value) {

          // searchList.value.forEach((item: ISearchList) => {
          if (!item.notinsearch) {
            const objitem: any = {}
            // console.log('        item ', item)
            const obj: any = {}

            if (item.table === 'regions') {

              const myfield = tools.getFieldSearchByTable(mytable.value, item.table, 'mycities.reg')
              obj[myfield] = item.value
              if (myfield) {
                obj['mycities.reg'] = item.value
                if (item.value !== '' && item.value !== costanti.FILTER_TUTTI) {
                  filtersearch3and.push(obj)
                }
              }

              if (item.value && recProvince && idRegion !== costanti.FILTER_TUTTI) {
                arrfilter_provices.push({ key: 'reg', value: idRegion })
              }

            } else if (item.table === 'circuits') {
              const myfield = tools.getFieldSearchByTable(mytable.value, item.table, 'profile.mycircuits.circuitname')
              obj[myfield] = item.value
              if (myfield) {
                if (item.value !== '' && item.value !== costanti.FILTER_TUTTI) {
                  let nomecircuito = item.value
                  if (tools.isObject(item.value))
                    nomecircuito = item.value.name

                  filtersearch3and.push({ "profile.mycircuits.circuitname": nomecircuito })
                }
              }

            } else if (item.table === 'provinces') {

              const myfield = tools.getFieldSearchByTable(mytable.value, item.table, 'mycities.prov')
              obj[myfield] = item.value
              if (myfield) {
                if (item.value !== '' && item.value !== costanti.FILTER_TUTTI) {
                  filtersearch3and.push(obj)
                }
              }

              if (item.value && recCities && idProvince !== costanti.FILTER_TUTTI) {
                arrfilter_cities.push({ key: 'prov', value: idProvince })
              }

            } else if (item.table === shared_consts.TABFILTRI_UTENTE) {

              item.arrvalue.forEach((myitemsingle: any) => {
                if (myitemsingle === shared_consts.FILTER_USER_SENZA_PROVINCE) {
                  filtercustom.push({ 'profile.resid_province': { $exists: false } });
                } else if (myitemsingle === shared_consts.FILTER_USER_CON_CIRCUITO) {
                  filtercustom.push({
                    'profile.mycircuits': { $exists: true, $ne: [] }
                  });
                } else if (myitemsingle === shared_consts.FILTER_USER_ONLINE_6_MESI) {
                  const numgiorni_attivi = 30 * 6
                  const daytocheck = new Date();
                  daytocheck.setDate(daytocheck.getDate() - numgiorni_attivi);
                  daytocheck.setHours(0, 0, 0, 0)

                  filtercustom.push({ lasttimeonline: { $gt: daytocheck } })
                } else if (myitemsingle === shared_consts.FILTER_USER_SENZA_CIRCUITO) {
                  filtercustom.push({
                    $or: [
                      { 'profile.mycircuits': { $exists: false } },
                      { 'profile.mycircuits': { $eq: [] } }
                    ]
                  });
                } else if (myitemsingle === shared_consts.FILTER_USER_PROVINCE) {
                  filtercustom.push({ 'profile.resid_province': { $exists: true, $ne: '' } });
                } else if (myitemsingle === shared_consts.FILTER_USER_TELEGRAM_BLOCKED) {
                  filtercustom.push({ 'profile.teleg_id_old': { $gt: 1 } });
                } else if (myitemsingle === shared_consts.FILTER_NOTE) {
                  filtercustom.push({ 'profile.note': { $exists: true, $ne: '' } });
                } else if (myitemsingle === shared_consts.FILTER_DA_CONTATTARE) {
                  filtercustom.push({ 'profile.da_contattare': { $exists: true, $ne: false } });
                } else if (myitemsingle === shared_consts.FILTER_SENZA_NOTE) {
                  filtercustom.push({
                    $or: [
                      { 'profile.note': { $exists: false } },
                      { 'profile.note': { $exists: true, $eq: '' } }],

                  });
                } else if (myitemsingle === shared_consts.FILTER_USER_WITHOUT_USERNAME_TELEGRAM) {
                  filtercustom.push({
                    $or: [
                      { 'profile.username_telegram': { $exists: false } },
                      { 'profile.username_telegram': { $exists: true, $eq: '' } }],

                  });

                } else if (myitemsingle === shared_consts.FILTER_USER_NO_VERIFIED_APORTADOR) {
                  filtercustom.push({
                    verified_by_aportador: { $exists: false },
                  });
                } else if (myitemsingle === shared_consts.FILTER_USER_NO_TELEGRAM_ID) {
                  filtercustom.push({ 'profile.teleg_id': { $lt: 1 } });
                } else if (myitemsingle === shared_consts.FILTER_FACILITATORE) {
                  filtercustom.push({
                    perm: { $bitsAnySet: 0b1000 }
                  })
                  // { 'perm': { $bit: { and:  } } });
                }
              })

            } else if (item.table === 'cities') {

              if (tools.existProp(item.value, '_id')) {
                const myfield = tools.getFieldSearchByTable(mytable.value, item.table, 'idCity')
                if (myfield) {
                  obj[myfield] = item.value._id
                  if (item.value && item.value !== '' && item.value._id !== costanti.FILTER_TUTTI) {
                    filtersearch3and.push(obj)
                  }
                }
              }
            } else if (shared_consts.TABLES_WITH_FILTER_FIELD.includes(item.table)) {

              if (item.value) {
                if (item.value && item.value !== '' && item.value._id !== costanti.FILTER_TUTTI) {
                  const myr: any = globalStore.getRecordByTableSingle(item.table, item.value)

                  if (myr) {
                    filtercustom.push(myr.filter)
                  }

                }
              }
            } else if (shared_consts.TABLES_WITH_SPECIAL_FILTER.includes(item.table)) {

              objitem[item.key] = item.value
              filtercustom.push(objitem)

            } else if (shared_consts.COL_WITH_FILTER_GTE.includes(item.key)) {
              objitem[item.key] = item.value
              filter_gte.push(objitem)


            } else if (item.table === 'lista_editori') {

              if (item.value !== costanti.FILTER_TUTTI) {
                objitem[item.key] = item.value
                filtersearch.push(objitem)
              }

            } else if (item.value > 0 || (item.type === costanti.FieldType.boolean && item.value === true)) {
              objitem[item.key] = item.value
              filtersearch.push(objitem)

            } else if (item.arrvalue && item.arrvalue.length > 0) {

              const myarr = item.arrvalue.filter((value: any) => {
                if (typeof value === 'number') {
                  return value > 0
                }
                return true
              })

              const arr2: any = []

              if (item.table !== 'provinces') {
                if (shared_consts.COL_WITH_ARRFILTER_IN_AND.includes(item.key)) {
                  myarr.forEach((myval: any) => {
                    const objitem2: any = {}
                    objitem2[item.key] = myval
                    arr2.push(objitem2)
                  })

                  const obj2: any = {
                    $and: arr2
                  }
                  if (arr2.length > 0) {
                    filtersearch.push(obj2)
                  }
                } else {

                  myarr.forEach((myval: any) => {
                    const objitem2: any = {}
                    objitem2[item.key] = myval
                    arr2.push(objitem2)
                  })

                  const obj2: any = {
                    $or: arr2
                  }
                  if (arr2.length > 0) {
                    filtersearch.push(obj2)
                  }
                }
              }

            } else {
              if ((item.table === shared_consts.TABLES_MYSKILLS) && item.value === costanti.FILTER_TUTTI) {
                const obj2: any = {}

                if (idSector > 0) {
                  // idSector
                  // obj2['sector._id'] = idSector
                  obj2.idSector = idSector
                  filtersearch2.push(obj2)
                }
                if (idSkill > 0) {
                  // idSector
                  obj2.idSkill = idSkill
                  filtersearch2.push(obj2)
                }
              } else if ((item.table === 'goods') && item.value === costanti.FILTER_TUTTI) {
                const obj2: any = {}
                if (idSectorGood > 0) {
                  // idSectorGood
                  obj2['sectorGood._id'] = idSectorGood
                  filtersearch2.push(obj2)
                }
              } else if ((item.table === 'subskills') && item.value === costanti.FILTER_TUTTI) {
                const obj2: any = {}
                // idSector
                if (idSkill > 0) {
                  obj2['myskill._id'] = idSkill
                  filtersearch2.push(obj2)
                }
              }
            }

          }
        }
      }

      if (arrfilter_cities.length > 0 && recCities) {
        const myobjfilt: any = {}
        for (const myrec of arrfilter_cities) {
          myobjfilt[myrec.key] = myrec.value
        }
        recCities.filter_extra = myobjfilt
      }

      if (arrfilter_provices.length > 0 && recProvince) {
        const myobjfilt: any = {}
        for (const myrec of arrfilter_provices) {
          myobjfilt[myrec.key] = myrec.value
        }
        recProvince.filter_extra = myobjfilt
      }


      // console.log('filtersearch', filtersearch)

      if (props.prop_search) {
        let nosearch = false
        if (filtersearch.length <= 0 && !param_myfilter) {
          nosearch = true
          returnedData.value = []
          returnedCount = 0
        } else {
          /*if (props.keyMain) {
            nosearch = true
            filtersearch.forEach((rec: any) => {
              if (!!rec[props.keyMain]) {
                nosearch = false
              }
            })
          }*/
        }
        // if ((false && nosearch && props.finder) || (props.finder_noNull && nosearch)) {
        if ((props.finder_noNull || (props.finder_noNullFilters && getNumFilterSelected() === 0)) && nosearch) {
          returnedData.value = []
          returnedCount = 0
          return true
        }
      }

      // console.log('filtercustom', props.filtercustom)


      let params: IParamsQuery = {
        table: mytable.value,
        newvers: true,
        startRow,
        endRow,
        filter: param_myfilter,
        filterand: param_myfilterand,
        // @ts-ignore
        filtersearch,
        // @ts-ignore
        filtersearch2,
        filtersearch3or,
        filtersearch3and,
        // @ts-ignore
        filtercustom,
        // @ts-ignore
        filterextra: props.filterextra,
        // @ts-ignore
        filterextra2: props.filterextra2,
        // @ts-ignore
        filter_gte,
        sortBy: myobj,
        userId: userStore.my._id,
        codeId: '',
        options: props.options,
        noaut: props.noaut,
      }

      params.codeId = mycodeid.value

      // console.log('params', params)
      // console.log('props.extraparams', props.extraparams)

      let paramsMap = null

      if (showMap.value) {
        paramsMap = {
          searchByBoundariesMap: boundariesMap.value
        }
      }

      params = { ...params, ...props.extraparams }
      if (paramsMap) {
        params = { ...params, ...paramsMap }
      }

      const data = await globalStore.loadTable(params)

      if (data) {
        returnedData.value = data.rows
        returnedCount = data.count
      } else {
        returnedData.value = []
        returnedCount = 0
      }

      return true

    }

    function savefilter() {
      // console.log('Close')
      emit('savefilter', myfilterand)
    }

    function onRequest(myprops: any) {
      const { page, rowsPerPage, rowsNumber, sortBy, descending } = myprops.pagination
      const myfilternow = myfilter.value
      const myfilterandnow = myfilterand.value

      savefilter()

      if (!mytable.value) {
        startsearch.value = false
        return
      }


      // console.log('myfilterandnow', myfilterandnow, 'myfilterandnow', myfilterandnow)

      // console.log('onRequest', 'myfilter = ', myfilter.value)

      loading.value = true

      spinner_visible.value = true

      // update rowsCount with appropriate value

      // function all rows if "All" (0) is rowsel
      const fetchCount = rowsPerPage === 0 ? rowsNumber : rowsPerPage

      // calculate starting row of data
      const startRow = (page - 1) * rowsPerPage
      const endRow = startRow + fetchCount

      console.log('onRequest:  startRow', startRow, 'endRow', endRow)

      serverData.value = []

      // fetch data from "server"
      return fetchFromServer(startRow, endRow, myfilternow, myfilterandnow, sortBy, descending).then((ris: any) => {

        pagination.value.rowsNumber = getRowsNumberCount()

        // clear out existing data and add new
        if (!returnedData.value || returnedData.value.length === 0) {
          serverData.value = []
        } else {
          // if (serverData.length > 0)
          //   serverData.splice(0, serverData.length, ...returnedData)
          // else
          try {
            serverData.value = [...returnedData.value]
          } catch (e) {
            serverData.value = []
          }
        }

        // console.log('serverData', serverData)

        // don't forfunction to update local pagination object
        pagination.value.page = page
        pagination.value.rowsPerPage = rowsPerPage
        //pagination.value.sortBy = getObjSort(sortBy, descending)
        pagination.value.sortBy = sortBy
        // ordinam.value = sortBy
        ordinam_desc.value = descending
        pagination.value.descending = descending

        // console.log('pagination', pagination)

        // ...and turn of loading indicator
        loading.value = false
        spinner_visible.value = false
        changetable.value = false
        startsearch.value = false

        checkScrollPosition()
      })
    }

    function onUpdateData(index: number, myprops: any, done: any) {
      let { page, rowsPerPage, rowsNumber, sortBy, descending } = myprops.pagination
      const myfilternow = myfilter.value
      const myfilterandnow = myfilterand.value

      // console.log('onUpdateData')

      if (ordinam.value) {
        sortBy = ordinam.value
        descending = ordinam_desc.value
      }

      sortBy = getObjSort(sortBy, descending)

      savefilter()

      if (!mytable.value) {
        // console.log('   startsearch.value', startsearch.value)
        startsearch.value = false
        if (myinfscroll.value) {
          // @ts-ignore
          myinfscroll.value.resume()
        }
        done()
        alreadymounting.value = true
        return
      }

      // function all rows if "All" (0) is rowsel
      const fetchCount = rowsPerPage === 0 ? rowsNumber : rowsPerPage

      // calculate starting row of data
      const startRow = numRecLoaded.value
      const endRow = startRow + fetchCount
      // console.log('startRow', startRow, 'endRow', endRow, 'rowsNumber', pagination.value.rowsNumber)

      startsearch.value = true

      // console.log('   TRUE: startsearch.value', startsearch.value)

      if ((startRow < pagination.value.rowsNumber) || clickbuttsearch.value) {

        // fetch data from "server"
        return fetchFromServer(startRow, endRow, myfilternow, myfilterandnow, sortBy, descending).then((ris: any) => {

          try {
            pagination.value.rowsNumber = getRowsNumberCount()
          } catch (e) {
            console.error('Err', e)
          }
          // console.log('   ...rowsNumber', pagination.value.rowsNumber)

          if (!returnedData.value || returnedData.value.length === 0) {
            // no more data
          } else {
            try {
              numRecLoaded.value = numRecLoaded.value + (returnedData.value ? returnedData.value.length : 0)
              // console.log('   ...numRecLoaded.value', numRecLoaded.value)
              const toadd = []
              for (const elem of returnedData.value) {
                if (serverData.value.findIndex((rec: any) => rec._id === elem._id) < 0) {
                  toadd.push(elem)
                }
              }
              serverData.value = [...serverData.value, ...toadd]
            } catch (e) {
              serverData.value = []
            }
          }

          // don't forfunction to update local pagination object
          pagination.value.page = page
          pagination.value.rowsPerPage = rowsPerPage
          pagination.value.sortBy = getObjSort(sortBy, descending)
          // ordinam.value = sortBy
          ordinam_desc.value = descending
          pagination.value.descending = descending

          // console.log('pagination', pagination)

          // ...and turn of loading indicator
          changetable.value = false
          startsearch.value = false

          // console.log('   FINE- startsearch.value', startsearch.value)

          if (myinfscroll.value) {
            // @ts-ignore
            myinfscroll.value.resume()
          }

          // console.log('   ...DONE ')
          done(pagination.value.rowsNumber === 0 ? true : false)

          checkScrollPosition()

          alreadymounting.value = true
        })
      } else {
        startsearch.value = false
        if (myinfscroll.value) {
          // @ts-ignore
          myinfscroll.value.resume()
        }
        done()
      }
    }

    function refresh_arr() {
      const myarr = [...serverData.value]
      serverData.value = []
      serverData.value = [...myarr]
    }

    function refresh_table() {

      onRequest({
        pagination: pagination.value
      })
      rowclicksel.value = null
    }

    function refresh_infscroll(done: any) {
      // console.log('refresh_infscroll', 'pag', pagination.value.rowsNumber, 'done', done)
      rowclicksel.value = null

      onUpdateData(0,
        {
          pagination: pagination.value
        }, done)
    }



    function refresh() {
      // console.log('refresh', 'startsearch', startsearch.value)

      clickbuttsearch.value = true
      // console.log('refresh')
      if (startsearch.value)
        return false

      // console.log('REFRESH!')

      // Controllo se la Regione è su Tutti, allora la provincia e comune devono andare vuoti
      if (searchList.value) {
        const filtroRegioni = searchList.value.find((myrec) => myrec.table === toolsext.TABREGIONS) // check if exist
        if (filtroRegioni && filtroRegioni.value === costanti.FILTER_TUTTI) {
          const filtroProv = searchList.value.find((myrec) => myrec.table === toolsext.TABPROVINCE) // check if exist
          if (filtroProv) {
            filtroProv.value = costanti.FILTER_TUTTI
            tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + toolsext.TABPROVINCE, filtroProv.value)
          }
        }
        /*const filtroCircuito = searchList.value.find((myrec) => myrec.table === 'circuits')
        if (filtroCircuito && filtroCircuito.value !== costanti.FILTER_TUTTI) {
          const filtroProv = searchList.value.find((myrec) => myrec.table === toolsext.TABPROVINCE) // check if exist
          if (filtroProv && filtroRegioni) {
            filtroRegioni.value = costanti.FILTER_TUTTI
            filtroProv.value = costanti.FILTER_TUTTI
            tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + toolsext.TABREGIONS, filtroRegioni.value)
            tools.setCookie(tools.COOK_SEARCH + costanti.FILTER_SEP + mytable.value + costanti.FILTER_SEP + toolsext.TABPROVINCE, filtroProv.value)
          }
        }*/
      }

      startsearch.value = true

      serverData.value = []
      numRecLoaded.value = 0
      pagination.value.page = 0
      search.value = search.value ? search.value.trim() : ''

      // console.log('refresh')
      // console.log('search', search)
      if (!!search.value && search.value !== '')
        myfilter.value = search.value
      else
        myfilter.value = ''

      // console.log('myfilter', myfilter.value)

      if (shared_consts.VERTIC_SHOW_GRID.includes(myvertical.value)) {
        if (myinfscroll.value) {
          // @ts-ignore
          myinfscroll.value.stop()
        }

        refresh_infscroll(() => true)
      } else {
        refresh_table()
      }

      clickbuttsearch.value = false
    }

    watch(() => mycodeid.value, (newval, oldval) => {
      // console.log('REFRR - mycodeid.value', newval)
      refresh()
    })

    watch(() => userStore.updateTables, (newval, oldval) => {
      if (newval && (myvertical.value === costanti.VISUTABLE_USER_TABGROUP ||
        myvertical.value === costanti.VISUTABLE_USER_TABCIRCUIT ||
        myvertical.value === costanti.VISUTABLE_SCHEDA_GROUP ||
        myvertical.value === costanti.VISUTABLE_SCHEDA_USER ||
        (props.showType === costanti.SHOW_USERINFO))) {

        // console.log('REFRR - updateTables.value', newval)
        refresh()

        userStore.updateTables = false
      }
    })

    /*watch(() => myfilterand.value, (newval, oldval) => {
      refresh()
    })*/

    function isFacilitatore() {
      return userStore.isFacilitatore
    }

    function isAdmin() {
      return userStore.isAdmin
    }

    function disabilita() {
      if ((mytable.value === 'users') && (isFacilitatore() && !userStore.isAdmin && !userStore.isManager)) {
        return true
      }

      return false
    }

    function tableClass() {
      return ($q.dark.isActive ? 'bg-black' : 'bg-white')
    }

    function selItem(item: any, col: IColGridTable, inmodif?: boolean) {
      // console.log('selItem', item, col)
      if (col.jointable === toolsext.TABSECTORS) {
        // Sbianca la select della Categoria

        if (tools.existProp(item, 'idSkill')) {
          item.idSkill = costanti.FILTER_NESSUNO
          newRecord.value.idSkill = item.idSkill
        }
      } else if (col.jointable === toolsext.TABSECTORGOODS) {
        // Sbianca la select della Categoria Beni

        if (tools.existProp(item, 'idGood')) {
          item.idGood = costanti.FILTER_NESSUNO
          newRecord.value.idGood = item.idGood
          console.log('newRecord', newRecord)
        }
      }
      rowsel.value = item
      idsel = item._id
      colsel.value = col
    }

    function undoVal() {
      // console.log('undoVal', 'colsel', colsel.value, 'valprec', valPrec, 'colkey', colkey, 'selected', rowsel.value)
      // console.table(serverData)
      if (colsel.value) {
        if (colsel.value.subfield !== '') {
          if (rowsel.value[colsel.value.field!] === undefined)
            rowsel.value[colsel.value.field!] = {}
          rowsel.value[colsel.value.field!][colsel.value.subfield!] = valPrec
        } else {
          rowsel.value[colsel.value.field!] = valPrec
        }
      }

      // serverData[colsel] = valPrec

    }

    function SaveValdb(newVal: any, valinitial: any) {
      // console.log('SaveValdb', newVal)
      // console.log('SaveValue', newVal, 'rowsel', rowsel)

      colsel.value = colclicksel.value
      // console.log('colsel', colsel)
      SaveValue(newVal, valinitial)
      colsel.value = { name: '', field: '', sortable: false }
    }


    function showandsave(row: any, col: any, newval: any, valinitial: any) {
      console.log('showandsave CGridTable', row, col, newval)
      rowsel.value = row
      colsel.value = col
      idsel = row._id
      SaveValue(newval, valinitial)

      // rowclicksel = null
    }

    function annulla(val: any) {
      // console.log('GridTable annulla')
      /*
      if (newRecord.value) {
        globalStore.DeleteRec({ table: mytable.value, id: newRecord.value._id })
          .then((ris) => {
            // console.log('deleted', ris)
            serverData.value.pop(ris)
            newRecord.value = null
            return true
          })
      }

       */
      newRecordBool.value = false
      newRecord.value = {}
    }

    function SaveValue(newVal: any, valinitial: any) {
      // console.log('SaveValue', newVal)
      // console.log('rowsel', rowsel, 'colsel', colsel.value)
      let myfield = ''
      let subf = ''
      if (colsel.value) {
        myfield = colsel.value.field!
        subf = colsel.value.subfield!
      }

      let myrec = rowsel.value
      if (newRecordBool.value)
        myrec = newRecord.value

      if (myfield) {
        if (colsel.value) {
          // Update value in table memory
          if (subf !== '') {
            if (myrec[myfield] === undefined)
              myrec[myfield] = {}
            myrec[myfield][subf] = newVal
          } else {
            myrec[myfield] = newVal
          }
        }

        const mydata = {
          id: idsel,
          table: mytable.value,
          fieldsvalue: {}
        } as any


        if (colsel.value) {
          if (subf !== '') {
            if (mydata.fieldsvalue[myfield] === undefined) {
              mydata.fieldsvalue[myfield + '.' + subf] = newVal
            }
            // mydata.fieldsvalue[colsel.value.field][colsel.subfield] = newVal
          } else {
            mydata.fieldsvalue[myfield] = newVal
          }
        }

        valPrec = valinitial

        saveFieldValue(mydata)
      }
    }

    function updatedcol() {
      // console.log('updatedcol')
      if (mycolumns.value) {
        colVisib.value = []
        colNotVisib.value = []
        colExtra.value = []
        mycolumns.value.forEach((elem: IColGridTable) => {

          const mysub = elem.subfield ? elem.subfield : ''
          if (elem) {
            if (elem.field !== costanti.NOFIELD) {
              if (checkIfColShow(elem.field)) {
                colVisib.value.push(elem.field + mysub)
              } else {
                colNotVisib.value.push(elem.field + mysub)
              }
            }

            if (elem.visible && elem.field === costanti.NOFIELD) {
              colExtra.value.push(elem.name)
            }
          }
        })
      }
    }

    function getrows() {
      return pagination.value.rowsNumber
    }

    function createNewRecordDialog() {

      const mydata: any = {
        table: mytable.value,
        data: {}
      }

      // if (props.defaultnewrec)
      //   mydata.data = props.defaultnewrec()

      // console.log('DATA=', mydata.data)


      // @ts-ignore
      if (!tools.isEmptyObject(props.defaultnewrec)) {
        // @ts-ignore
        newRecord.value = props.defaultnewrec
      } else {
        newRecord.value = tools.getdefaultnewrec(mytable.value, { groupname: props.groupname })
      }
      if (!newRecord.value) {
        newRecordBool.value = false
        newRecord.value = {}
      }
      newRecord.value.userId = userStore.my._id
      newRecord.value.idapp = tools.getEnv('VITE_APP_ID')
      // globalStore.saveTable(mydata).then(ris => console.log('RISULT', ris))
      newRecordBool.value = true

    }


    function createNewRecord() {

      createNewRecordDialog()

      // console.log('newRecord.value', newRecord.value)

      // serverData.value.push(newRecord.value)
      pagination.value.rowsNumber++

      loading.value = false
    }

    function saveFieldValue(mydata: any) {
      // console.log('saveFieldValue', mydata)

      if (newRecordBool.value) {
        return false
      }

      // Save on Server
      globalStore.saveFieldValue(mydata).then((esito) => {
        if (esito) {
          tools.showPositiveNotif($q, t('db.recupdated'))
        } else {
          tools.showNegativeNotif($q, t('db.recfailed'))
          undoVal()
        }
      })
    }

    function created() {

      try {
        mytable.value = props.prop_mytable
        mytitle.value = props.prop_mytitle
        mytitlenew.value = props.prop_mytitlenew
        mycolumns.value = props.prop_mycolumns
        colkey.value = props.prop_colkey
        pagination.value = props.prop_pagination

        myvertical.value = props.vertical

        if (props.prop_search) {
          showfilter.value = props.prop_showfilter || true
        } else {
          showfilter.value = props.prop_showfilter
        }

      } catch (e) {
        console.error('ERRORE', e)
      }
    }

    const checkScrollPosition = () => {
      // console.log('checkScrollPosition')
      const container = carouselTabRef.value
      if (!container) return

      if (!addEventScroll.value && carouselTabRef.value) {
        carouselTabRef.value?.addEventListener('scroll', checkScrollPosition)
        addEventScroll.value = true
      }

      if (carouselTabRef.value) {
        console.log('carouselTabRef LISTEN')
      } else {
        console.log('carouselTabRef NO !')
      }
      console.log('  .... >>> AVANTI ', container.scrollLeft, container.clientWidth)

      isAtStart.value = container.scrollLeft <= 0
      isAtEnd.value = container.scrollLeft + container.clientWidth >= container.scrollWidth - 1

      if (serverData.value.length > 0) { // Assicurarsi che ci siano elementi
        console.log('entro dentro...')
        const cardWidth = container.scrollWidth / serverData.value.length
        activeIndex.value = Math.round(container.scrollLeft / cardWidth)
      }
    }

    const scroll = (direction: any) => {
      const container = carouselTabRef.value;
      if (!container || !serverData.value.length) return;

      const cardWidth = container.scrollWidth / serverData.value.length;
      container.scrollBy({
        left: direction * cardWidth,
        behavior: 'smooth',
      });
    };

    function mounted() {
      // console.log('mounted...')
      try {
        searchList.value = props.prop_searchList

        boundariesMap.value = getMapBoundaries()

        showMap.value = props.prop_showMap
        showMapAtLeast1.value = props.prop_showMap

        // console.log('GridTable mounted', tablesel.value)

        // console.log('props.filtercustom', props.filtercustom)


        if (props.tablesList) {
          canEdit.value = tools.getCookie(tools.CAN_EDIT, canEdit) === 'true'
          tablesel.value = tools.getCookie('tablesel', tablesel.value)
        }

        myfilterand.value = props.filterdef
        // myfiltercustom.value = props.filtercustom
        // console.log('tablesel', tablesel)

        if (tablesel.value === '') {
          if (props.tablesList)
            tablesel.value = props.tablesList[0].value
          else
            tablesel.value = mytable.value
        }

        if (!shared_consts.TABLES_ORDER_DATE_UPDATED.includes(tablesel.value) &&
          !shared_consts.TABLES_ORDER_DESCR.includes(tablesel.value)) {
          // console.log('get cookie)')
          const v1 = tools.getCookie('s_ordinamnew_' + tablesel.value, null)
          if (v1)
            ordinam.value = v1
          const v2 = tools.getCookie('s_ordinamnew_des_' + tablesel.value, null)
          if (v2)
            ordinam_desc.value = v2
        }

        // console.log('2) tablesel', tablesel.value)

        changeTable(tablesel.value)

        nextTick(() => {
          checkScrollPosition()
        })

        // Aggiungi gli listener agli eventi della tastiera
        document.addEventListener('keydown', onEscapeKey);
        // window.addEventListener('popstate', onBackButton);

      } catch (error) {
        console.error('Err mounted', error)
      }
    }

    function exec_func_table(table: string, func: number, par: IParamDialog) {


      if (func === lists.MenuAction.DELETE_RECTABLE) {
        globalStore.DeleteRec({ table, id: par.param1 }).then((ris) => {
          if (ris) {
            ActionAfterYes(func, par.param2, null)
            tools.showPositiveNotif($q, t('db.deletedrecord'))
          } else {
            tools.showNegativeNotif($q, t('db.recdelfailed'))
          }
        })
      } else if (func === lists.MenuAction.DUPLICATE_RECTABLE) {
        globalStore.DuplicateRec({ table, id: par.param1 }).then((ris) => {
          if (ris) {
            ActionAfterYes(func, par.param2, ris.data)
            tools.showPositiveNotif($q, t('db.duplicatedrecord'))
          } else
            tools.showNegativeNotif($q, t('db.recdupfailed'))
        })
      }
    }


    function clickFunz(item: any, col: IColGridTable) {
      if (!!col && col.action) {

        const table = mytable.value
        const ok = translate('dialog.yes')
        const cancel = translate('dialog.no')
        const funccancel = 0
        const par = {
          param1: item._id,
          param2: { ...item },
        }

        if (col.action === lists.MenuAction.CAN_EDIT_TABLE) {
          console.log('Edit', item)
          selItem(item, col)
          recModif.value = { ...item }
          recSaved.value = { ...item }
          editRecordBool.value = true
        } else {

          let mymsgquestion = translate(col.askaction) + '?'
          if (col.action === lists.MenuAction.DELETE_RECTABLE) {
            mymsgquestion = 'Cancellare ' + tools.getNomeTabellaStrByTable(table, item) + '?';
          }

          return $q.dialog({
            message: mymsgquestion,
            html: true,
            ok: {
              label: ok,
              push: true,
            },
            title: translate(col.label_trans),
            cancel: true,
            persistent: false,
          }).onOk(() => {
            // console.log('OK')
            exec_func_table(table, col.action, par)
            return true
          }).onCancel(() => {
            // console.log('CANCEL')
            exec_func_table(table, funccancel, par)
            return false
          })
        }

      }
    }

    function ActionAfterYes(action: number, item: any, data?: any) {

      if (action === lists.MenuAction.DELETE_RECTABLE) {
        if ((serverData.value.length > 0) && item) {
          console.log('item', item)
          const indelim = serverData.value.findIndex((rec: any) => rec._id === item._id)
          console.log('indexof', indelim)
          if (indelim >= 0)
            serverData.value.splice(indelim, 1)
          refresh_arr()
        }
      } else if (action === lists.MenuAction.DUPLICATE_RECTABLE) {
        // Add record duplicated
        // serverData.push(data)
        refresh()
      }
    }

    function visCol(col: IColGridTable) {
      if ((!tools.isBitActive(col.showWhen, costanti.showWhen.NewRec)) && !tools.isBitActive(col.showWhen, costanti.showWhen.InView)
        && !tools.isBitActive(col.showWhen, costanti.showWhen.InView_OnlyifExist) && tools.isBitActive(col.showWhen, costanti.showWhen.InEdit)) {
        return (canEdit.value)
      } else {
        return true
      }
    }

    function clByCol(col: IColGridTable) {
      if (!visuIntestazCol(col)) {
        return 'row justify-center vertical-middle'
      } else {
        return ''
      }
    }

    function visuIntestazCol(col: IColGridTable) {
      if (col.fieldtype === costanti.FieldType.html || col.fieldtype === costanti.FieldType.listimages || col.fieldtype === costanti.FieldType.listobj || col.noshowlabel) {
        return false
      } else {
        return true
      }
    }

    function checkIfColShow(field: string | undefined) {
      const vis = true
      /*if (shared_consts.TABLES_NOT_SHOW_IF_USERNAME.includes(props.prop_mytable) && !props.prop_search) {
        if (field === 'username') {
          vis = false
        }
      }*/
      return vis
    }

    function changeCol(newval: any) {
      // console.log('changecol', mytable.value)
      if (mytable.value) {
        const arrcol = []
        let col: IColGridTable = { name: '', sortable: false }
        for (col of mycolumns.value) {
          if (col.field !== costanti.NOFIELD) {
            const obj = {
              n: col.field + (col.subfield ? col.subfield : ''),
              v: 0
            }
            obj.v = colVisib.value.includes(obj.n) ? 1 : 0
            if (obj.v === 0) {
              // scrive solo quelli da nascondere !
              arrcol.push(obj.n + ',' + obj.v)
            }
          }
        }

        tools.setCookie(mytable.value + '_', arrcol.join('|'))
      }
    }

    function changeTable(mysel: any) {
      // console.log('changeTable', tablesel.value)
      changetable.value = true
      if (tablesel.value === undefined || tablesel.value === '')
        return

      // console.log('changeTable mysel=', mysel, 'tablesel', tablesel.value)
      // console.log('tablesList=')
      // console.table(tablesList)

      let mytab = null
      if (props.tablesList) {
        mytab = props.tablesList.find((rec: any) => rec.value === mysel)
      }

      if (mytab === undefined) {
        tablesel.value = props.tablesList[0].value
        if (props.tablesList) {
          mytab = props.tablesList.find((rec: any) => rec.value === tablesel.value)
        }
      }

      // console.log('tablesel', tablesel.value, 'mytab', mytab)

      if (mytab) {
        mytitle.value = mytab.label
        colkey.value = mytab.colkey
        if (mytab.columns) {
          // @ts-ignore
          mycolumns.value = [...mytab.columns]
        }
      }

      // console.log('mycolumns')
      // console.log(mycolumns)
      // console.log('tablesList:')
      // console.table(tablesList)

      if (mycolumns.value) {
        mycolumns.value.forEach((rec: IColGridTable) => {
          if (rec.label_trans)
            rec.label = t(rec.label_trans)
        })
      }

      if (mytab) {
        mytable.value = mytab.value
      }

      if (props.tablesList) {
        tools.setCookie('tablesel', tablesel.value)
      }

      updatedcol()

      if (mytable.value) {
        // Leggi la lista delle colonne visibili:
        const myselcol = tools.getCookie(mytable.value + '_', '')

        colVisib.value = []

        let elem: IColGridTable
        if (tools.isArray(mycolumns.value)) {
          for (elem of mycolumns.value) {
            if (elem.field !== costanti.NOFIELD) {
              if (checkIfColShow(elem.field)) {
                colVisib.value.push(elem.field! + elem.subfield!)
              }
            }
          }


          if (!!myselcol && myselcol.length > 0) {
            const arrselcol = myselcol.split('|')

            for (const col of arrselcol) {
              const arrv = col.split(',')
              if (arrv.length > 1) {
                const field = arrv[0]
                const visib = arrv[1]
                const rec = mycolumns.value.find((myrec: any) => (myrec.field + myrec.subfield) === field)


                if (rec) {
                  if (field) {
                    if (visib === '1') {
                      if (!colVisib.value.includes(field))
                        colVisib.value.push(field)  // se non incluso allora lo aggiungi
                    } else if (visib === '0') {
                      // Se da togliere, lo togli
                      if (colVisib.value.includes(field))
                        if (colVisib.value)
                          colVisib.value = colVisib.value.filter((myrec: any) => myrec !== field)
                    }
                  }
                }
              }
            }
          }
        }
      }

      // console.log('REFRR - changetable')
      refresh()
    }

    function doSearch() {
      //  console.log('REFRR - doSearch')
      refresh()
    }
    function doSort() {

      refresh()
    }

    function changefuncAct(newval: any) {
      if (!disabilita()) {
        tools.setCookie(tools.CAN_EDIT, newval)
      }
    }

    function clickrowcol(row: any, col: any) {
      if (!canEdit.value) {
        if (!selected.value[0]) {
          const uguali = rowclicksel.value!._id === row._id
          console.log('id', rowclicksel.value!._id, 'id2', row._id)
          rowclicksel.value = null
          colclicksel.value = null
        } else {
          rowclicksel.value = row
          colclicksel.value = col
        }
      }
    }

    function getclrow(myrow: any) {
      if (rowclicksel.value === myrow)
        return 'colsel'
      else
        return ''
    }

    function getSelectedString() {
      return selected.value.length === 0 ? '' : `${selected.value.length} record${selected.value.length > 1 ? 's' : ''} selected of ${serverData.value.length}`
    }

    function selectionclick(details: any) {
      // console.log('selectionclick selected', selected, 'details', details)
      if (details.added) {
        rowclicksel.value = details.rows[0]
        colclicksel.value = details.keys[0]
      } else {
        rowclicksel.value = null
        colclicksel.value = null
      }

      // console.log('rowclicksel', rowclicksel)
    }

    function getusernamesel() {
      try {
        if (rowclicksel.value) {
          return rowclicksel.value.username
        }
      } catch (e) {
        return ''
      }
    }

    function enableSaveNewRec(newrec: boolean, showmsg: boolean = true) {

      const ok = true

      try {

        let myrec = null
        if (newrec) {
          myrec = { ...newRecord.value }
        } else {
          myrec = { ...recModif.value }
        }

        // mycolumns.value.forEach((col: IColGridTable) => {
        let col: IColGridTable

        let msg = ''

        for (col of mycolumns.value) {
          if (!msg) {
            if (col.showonlyif_dipersona) {
              const valori = myrec['idStatusSkill']

              if (valori && (valori.length === 1) && valori.includes(shared_consts.STATUSSKILL_ONLINE)) {
                col.required = false
              } else {
                col.required = true
              }

              col.visible = col.required
            }
            if (col.required) {
              // console.log('newRecord.value', newRecord.value, newRecord.value[col.name])
              if (tools.isArray(myrec[col.name])) {
                if (myrec[col.name].length <= 0) {
                  msg = 'Si prega di compilare il campo \'' + getColMissing(myrec) + '\''
                }
              } else {
                if (!myrec[col.name]) {
                  msg = 'Si prega di compilare il campo \'' + getColMissing(myrec) + '\''
                }
              }
            }
            if (!msg && col.maxlength! > 0 && myrec && myrec[col.name]) {
              if ((myrec[col.name].length > col.maxlength!) && (col.fieldtype !== costanti.FieldType.html)) {
                msg = t('annunci.maxlength', { name: translate(col.label_trans), maxlength: col.maxlength })
              }
            }
            if (!msg && col.minlength! > 0 && myrec && myrec[col.name]) {
              if ((myrec[col.name].length < col.minlength!) && (col.fieldtype !== costanti.FieldType.html)) {
                msg = t('annunci.minlength', { name: translate(col.label_trans), minlength: col.minlength })
              }
            }
          }
        }

        if (showmsg && msg) {
          tools.showNegativeNotif($q, msg, 5000)
          return false
        }
      } catch (e) {

      }

      return ok
    }

    function getColMissing(myrec: any) {

      let col: IColGridTable

      for (col of mycolumns.value) {
        if (col.required) {
          // console.log('newRecord.value', newRecord.value, newRecord.value[col.name])
          if (tools.isArray(myrec[col.name])) {
            if (myrec[col.name].length <= 0) {
              return translate(col.label_trans)
            }
          } else {
            if (!myrec[col.name]) {
              // console.log('col.name', col.name)
              return translate(col.label_trans)
            }
          }
        }
      }

      return ''
    }

    async function saveNewRecord() {
      // check if the field are setted

      if (!enableSaveNewRec(true)) {
        return false
      }

      console.log('saveNewRecord')
      const mydata = {
        table: mytable.value,
        data: {}
      }

      const myobj = newRecord.value


      // ++ Eliminare eventuali campi ?
      mycolumns.value.forEach((col: IColGridTable) => {
        if (col.notsave) {
          delete myobj[col.name]
        }
        // Add the column
        if (col.field_toduplicate_nospace) {
          //
          const trovato = tools.removespecial_chars(myobj[col.name])
          if (myobj[col.field_toduplicate_nospace] === '') {
            myobj[col.field_toduplicate_nospace] = trovato
          }
          const attuale = tools.removespecial_chars(myobj[col.field_toduplicate_nospace])
          myobj[col.field_toduplicate_nospace] = attuale
          // console.log('trovato', trovato, 'name', myobj[col.name], 'duplicate:', myobj[col.field_toduplicate_nospace], 'orig', myobj[col.name])
        }
      })

      mydata.data = myobj

      const data = await globalStore.saveTable(mydata)
        .then((ris) => {
          if (tools.existProp(ris, 'code')) {
            tools.checkErrors($q, ris.code, '')
          } else {
            if (ris) {
              // console.log('ris', ris)
              newRecordBool.value = false
              const indrec = serverData.value.findIndex((rec: any) => rec._id === ris._id)
              console.log('indrec', indrec, serverData.value[indrec])

              if (fieldsTable.tableWithUsername.includes(props.prop_mytable)) {
                ris.username = userStore.my.username
              }

              if (userStore.my.profile) {
                if (fieldsTable.tableforEnableCircuits.includes(props.prop_mytable)) {
                  if (!userStore.my.profile.calc.numGoodsAndServices)
                    userStore.my.profile.calc.numGoodsAndServices = 1
                  else
                    userStore.my.profile.calc.numGoodsAndServices += 1
                }
              }

              // console.table(serverData.value)
              if (indrec >= 0)
                serverData.value[indrec] = ris
              else
                serverData.value = [ris, ...serverData.value]

              newRecord.value = {}
              newRecordBool.value = false

              tools.showPositiveNotif($q, t('db.recupdated'))
              // refresh()
            } else {
              tools.showNegativeNotif($q, t('db.recfailed'))
            }
          }
        }).catch((e) => {
          tools.showNegativeNotif($q, t('db.recfailed'))
        })
    }

    function cancelrecModif() {
      recModif.value = { ...recSaved.value }

      editRecordBool.value = false
      /*if (recModif.value._id) {
        const indrec = serverData.value.findIndex((rec: any) => rec._id === recModif.value._id)
        if (indrec >= 0)
          serverData.value[indrec] = recModif.value
        editRecordBool.value = false
      }

       */
    }

    async function saverecModif() {
      // console.log('saverecModif', recModif.value)
      const mydata = {
        table: mytable.value,
        data: {}
      }

      if (!enableSaveNewRec(false)) {
        return false
      }


      mydata.data = recModif.value

      const oldrec = serverData.value.find((rec: IMySkill) => rec._id === recModif.value._id)

      const data = await globalStore.saveTable(mydata)
        .then((ris) => {
          // console.log('ris', ris)
          if (ris) {
            editRecordBool.value = false
            const indrec = serverData.value.findIndex((rec: any) => rec._id === ris._id)
            console.log('indrec', indrec, serverData.value[indrec])
            mycolumns.value.forEach((col: IColGridTable) => {
              if (!col.foredit) {
                ris[col.name] = oldrec[col.name]
              }
            })
            if (indrec >= 0)
              serverData.value[indrec] = ris
          }
        })
    }


    function getlabelAddRow() {
      return props.labelBtnAddRow
    }

    function visButtRow() {
      return (props.labelBtnAddRow !== addRow.value) && props.labelBtnAddRow !== 'NONE'
    }

    function checkIfShowRec(rec: any) {
      return ((rec._id > 0 && typeof rec._id === 'number') || rec._id !== 'number') && rec !== -100
    }

    function showColCheck(col: IColGridTable, tipovis: number, visulabel: boolean, value: any = '', record: any = null) {

      if (col.isadvanced_field && !showfilteradv.value)
        return false

      const check = tools.checkIfShowField(col, tipovis, visulabel, value)

      let valuePresent = (colVisib.value.includes(col.field! + col.subfield) || colVisib.value.includes(col.field + '.' + col.subfield))

      if (valuePresent && col.visibleif! > 0 && record) {
        if (col.visib_field) {
          if (col.visibleif === costanti.BINARY_CHECK) {
            if (!tools.isBitActive(record[col.visib_field], col.visib_value))
              valuePresent = false
          }

        }

      }

      return check && valuePresent
    }

    function getValueExtra(col: IColGridTable, record: any) {
      if (record) {
        if (col.filter_field! in record) {
          return col.filter_field ? record[col.filter_field] || '' : ''
        }
      }
      return ''
    }


    function cmdExt(cmd: any, id: any, myrec: any) {
      console.log('cmd', cmd)

      if (cmd === costanti.CMD_CLONE) {
        const myarr = serverData.value.find((rec: any) => rec._id === id)
        newRecord.value = myarr
        newRecord.value._id = 0
        newRecordBool.value = true
        return true;
      }

      if (cmd === costanti.CMD_SHOW_PAGE) {
        visupagedialog.value = true
        myrecdialog.value = myrec
        myIdRecDialog.value = id
        return true
      } else if (cmd === costanti.CMD_OPEN_PAGE) {
        router.push(tools.getPathByTableAndRec(mytable.value, myrec))
        return true
      }

      let action = 0
      if (cmd === costanti.CMD_DELETE) {
        action = lists.MenuAction.DELETE_RECTABLE
      } else if (cmd === costanti.CMD_MODIFY) {
        action = lists.MenuAction.CAN_EDIT_TABLE
      } else if (cmd === costanti.CMD_DUPLICATE) {
        action = lists.MenuAction.DUPLICATE_RECTABLE
      }


      if (action > 0) {

        const col = props.prop_mycolumns.find((rec: any) => rec.action === action)
        if (col) {
          // console.log('col action', col)
          const myarr = serverData.value.find((rec: any) => rec._id === id)
          if (myarr)
            clickFunz(myarr, col)
        }
      }
    }

    function showDate(mydate: any) {
      console.log('showDate', mydate)
      const datestr = tools.getstrVeryShortDate(mydate)
      if (actualDate.value !== datestr) {
        return true
      }
      return false
    }

    function getActualDate(mydate: any) {
      return actualDate.value
    }

    function onLoadScroll(index: number, done: any) {
      // console.log('onLoadScroll', index)

      if (index > 1) {
        // console.log('onLoadScroll', index, 'RECLOAD', numRecLoaded.value, 'ROWS: ', pagination.value.rowsNumber, 'PAGE: ', pagination.value.page)
        if ((numRecLoaded.value < pagination.value.rowsNumber || (pagination.value.rowsNumber <= 0 && clickbuttsearch.value))) {
          if (pagination.value.rowsNumber === 0) {
            pagination.value.page = 0
          }

          pagination.value.page = pagination.value.page + 1
          refresh_infscroll(done)
        } else {
          done(true)
        }
      } else {
        // console.log('DONE .....................')
        done()
      }
    }

    function wrapCsvValue(val: any, formatFn?: any, row?: any, col?: IColGridTable) {
      let formatted = formatFn !== void 0
        ? formatFn(val, row)
        : val

      formatted = formatted === void 0 || formatted === null
        ? ''
        : String(formatted)

      formatted = formatted.split('"').join('""')
      /**
       * Excel accepts \n and \r in strings, but some other CSV parsers do not
       * Uncomment the next two lines to escape new lines
       */
      // .split('\n').join('\\n')
      // .split('\r').join('\\r')

      if (col) {
        if (col.label_trans === t('movement.accountFromId')) {
          // ..
        }
      }

      if (col)
        console.log(' valu', formatted, ' (col=', col.name)

      return `"${formatted}"`
    }

    // onMounted(mounted)
    function exportTable() {
      // console.log('row', serverData.value)
      // console.log('mycolumns.value', mycolumns.value)
      // naive encoding to csv format
      const headers = mycolumns.value.map((col: any) => wrapCsvValue(col.label));
      const rows = serverData.value.map((row: any) =>
        mycolumns.value.map((col: any) => {
          const value = typeof col.field === 'function'
            ? col.field(row)
            : tools.getValue(row, col.field, col.subfield);
          return wrapCsvValue(value, col.format, row, col);
        }).join('|')
      );

      const content = [headers.join('|'), ...rows].join('\r\n');

      const status = exportFile(
        'export-' + mytable.value + '_' + tools.getstrYYMMDDHHMMDateTime(tools.getDateNow()) + '.csv',
        content,
        'text/csv'
      )

      if (status !== true) {
        $q.notify({
          message: 'Il Browser ha negato il download del file.',
          color: 'negative',
          icon: 'warning'
        })
      }
    }

    function update_col(col: string, value: string) {
      // console.log('update_col', col, value)


      if (col) {
        if (newRecordBool.value) {
          newRecord.value[col] = value
        } else {
          recModif.value[col] = value
        }
      }

      enableSaveNewRec(newRecordBool.value, false)

    }

    function setShowMonth(row: any, index: number) {
      if (actmonth.value !== tools.getstrMonth(row.dateTimeStart)) {
        actmonth.value = tools.getstrMonth(row.dateTimeStart)
        drawmonth.value = true
      } else {
        drawmonth.value = false
      }

      return drawmonth.value
    }

    function ifShowMonth() {
      return drawmonth.value
    }

    /*function showNotification() {
      router.push('/notifs')
    } */

    // Questa funzione viene chiamata quando il dialogo cerca di chiudersi
    const onEscapeKey = (event: KeyboardEvent) => {
      // console.log('onEscapeKey', event.key)
      if (event.key === 'Escape') {
        event.preventDefault(); // Previene la chiusura da ESC
      }
    };

    // Rimuovi i listener al distruggere del componente
    onBeforeUnmount(() => {
      document.removeEventListener('keydown', onEscapeKey);

      carouselTabRef.value?.removeEventListener('scroll', checkScrollPosition)

      stopAutoplay()

      // window.removeEventListener('popstate', onBackButton);
    });

    onMounted(() => {
      mounted()
    })

    function hidewindow() {
      annulla(0)
    }

    function clickMarker(id: any) {
      console.log('clickMarker', id)
      cmdExt(costanti.CMD_SHOW_PAGE, id, null)
    }

    function updateMapBoundaries(ne: any, sw: any, updatedata: boolean) {

      if (ne && sw) {
        // console.log('updateMapBoundaries', ne, sw)

        mapInitialized.value = true
        boundariesMap.value = { ne, sw }

        // Verifica se boundariesMap è variato da precedente valore,
        // ma solo se ci sono nuovi pezzi delle mappa in più mostrati, quindi se è stato fatto un zoom in, non includerlo

        const percrange = 0.15 //15%

        const percrange_ne_lat = ne.lat - ((ne.lat - sw.lat) * percrange)
        const percrange_ne_lng = ne.lng - ((ne.lng - sw.lng) * percrange)
        const percrange_sw_lat = sw.lat + ((ne.lat - sw.lat) * percrange)
        const percrange_sw_lng = sw.lng + ((ne.lng - sw.lng) * percrange)


        if (precboundariesMap.value) {
          if (precboundariesMap.value.ne.lat > percrange_ne_lat && precboundariesMap.value.ne.lng > percrange_ne_lng &&
            precboundariesMap.value.sw.lat < percrange_sw_lat && precboundariesMap.value.sw.lng < percrange_sw_lng) {
            updatedata = false
            // console.log('updateMapBoundaries', 'updatedata', updatedata)
          } else {
            // updatedata = false
          }
        }


        if (updatedata) {
          precboundariesMap.value = boundariesMap.value
          // console.log('   doSearch in updateMapBoundaries... ', ne, sw)
          if (autoaggiornaMappaSeMuovi.value) {
            doSearch()
          } else {

          }

        }
      }

    }

    function updateMapZoomOut() {
      // console.log('updateMapZoomOut')
      doSearch()
    }

    function clickButtBar(idbutt: any) {
      if (idbutt === tools.BUTT_ADDREC) {
        createNewRecord()
      }
    }

    function getLabelAreaMap(conHtml: boolean = true) {
      if (showMap.value) {
        if (conHtml) {
          return '<span class="hint_search">' + translate('grid.intheareamap') + '</span>'
        } else {
          return translate('grid.intheareamap')
        }

      }

      return ''
    }

    function gotoCurrentLocation() {
      myMapComp.value.gotoCurrentLocation()
    }

    function showInMap(rec: any) {
      visupagedialog.value = false

      if (!showMap.value) {
        showMapAtLeast1.value = true
        showMap.value = true
      }

      if (myMapComp.value && mapInitialized.value) {
        myMapComp.value.showInMap(rec)
      }
    }

    function handleTransition(newVal: any, oldVal: any) {
      // Se siamo vicini alla fine degli elementi caricati, carichiamo altri elementi
      if (serverData.value.length - newVal <= 2 && !loading.value) {
        onLoadScroll(newVal, () => { })
      }
    }

    async function loadMore(index: any, done: any) {
      if (loading.value) {
        done()
        return
      }

      loading.value = true

      try {
        refresh_infscroll(done)
      } catch (error) {
        console.error('Errore nel caricamento:', error)
        done()
      } finally {
        loading.value = false
      }
    }

    const startAutoplay = () => {
      if (autoplay.value && !autoplayInterval.value) {
        autoplayInterval.value = setInterval(() => {
          autoplay.value = true
        }, 3000) // Intervallo di 3 secondi
      } else {
        autoplay.value = true
      }
    }

    const stopAutoplay = () => {
      if (autoplayInterval.value) {
        clearInterval(autoplayInterval.value)
        autoplayInterval.value = null
      }
      autoplay.value = false
    }

    const onIntersection = (entry: any) => {
      if (entry.isIntersecting) {
        // console.log('PARTITO INTERSECTION!')
        startAutoplay()
      } else {
        // console.log(' USCITO DALL\'INTERSEZIONE! !!!')
        stopAutoplay()
      }
    }

    function getisDettagliByCatalog() {
      const rec = searchList.value.find((myrec) => myrec.table === shared_consts.TABLES_CATALOG && myrec.key === 'dettagli')
      if (rec) {
        return rec.value
      }

      return false
    }


    created()

    return {
      selItem,
      SaveValdb,
      showandsave,
      annulla,
      SaveValue,
      updatedcol,
      getrows,
      createNewRecordDialog,
      createNewRecord,
      saveFieldValue,
      clickFunz,
      visCol,
      visuIntestazCol,
      clByCol,
      changeCol,
      changeTable,
      doSearch,
      changefuncAct,
      clickrowcol,
      getclrow,
      getSelectedString,
      selectionclick,
      getusernamesel,
      saveNewRecord,
      saverecModif,
      cancelrecModif,
      hidewindow,
      isfinishLoading,
      getlabelAddRow,
      visButtRow,
      mytable,
      mytitle,
      mytitlenew,
      mycolumns,
      colkey,
      search,
      canEdit,
      rowclicksel,
      colVisib,
      colExtra,
      colclicksel,
      selected,
      pagination,
      loading,
      onRequest,
      serverData,
      myfilter,
      disabilita,
      newRecordBool,
      editRecordBool,
      newRecord,
      recModif,
      recSaved,
      lists,
      refresh,
      spinner_visible,
      tablesel,
      myfilterand,
      tools,
      costanti,
      toolsext,
      fieldsTable,
      globalStore,
      searchList,
      searchval,
      checkIfShowRec,
      valoriopt,
      labelcombo,
      filter,
      filtergrp,
      myvertical,
      showColCheck,
      getValueExtra,
      shared_consts,
      showfilter,
      cmdExt,
      visupagedialog,
      myrecdialog,
      myIdRecDialog,
      showDate,
      getActualDate,
      actualDate,
      actual,
      isAdmin,
      onLoadScroll,
      numRecLoaded,
      myinfscroll,
      t,
      exportTable,
      showNotification,
      editOn,
      showSpin,
      userStore,
      doSort,
      ordinam,
      ordinam_desc,
      getNumFilterSelected,
      rowsel,
      showInnerDialog,
      lengthopt,
      update_col,
      startsearch,
      getNumRecFromQuery,
      actmonth,
      alreadymounting,
      withdate,
      setShowMonth,
      ifShowMonth,
      showMap,
      clickMarker,
      updateMapBoundaries,
      updateMapZoomOut,
      clickButtBar,
      showSearchDialog,
      getLabelAreaMap,
      myMapComp,
      gotoCurrentLocation,
      showInMap,
      showMapAtLeast1,
      carouselTabRef,
      isAtStart,
      isAtEnd,
      activeIndex,
      scroll,
      slideGridOriz,
      autoplay,
      onUpdateData,
      scrollTargetId,
      handleTransition,
      loadMore,
      onIntersection,
      showfilteradv,
      getisDettagliByCatalog,
    }
  }
})
