<script setup>
import {useTempStore} from "~/stores/temp.js";
import FloatingActionButton from "~/components/mobile/FloatingActionButton.vue";
import EntityTable from "~/components/EntityTable.vue";
import EntityTableMobile from "~/components/EntityTableMobile.vue";
import {setPageLayout} from "#app";

const { has } = usePermission()

const platformIsNative = false

defineShortcuts({
  '/': () => {
    //console.log(searchinput)
    //searchinput.value.focus()
    document.getElementById("searchinput").focus()
  },
  '+': () => {
    router.push(`/standardEntity/${type}/create`)
  },
  'Enter': {
    usingInput: true,
    handler: () => {
      router.push(`/standardEntity/${type}/show/${items.value[selectedItem.value].id}`)
    }
  },
  'arrowdown': () => {
    if(selectedItem.value < items.value.length - 1) {
      selectedItem.value += 1
    } else {
      selectedItem.value = 0
    }
  },
  'arrowup': () => {
    if(selectedItem.value === 0) {
      selectedItem.value = items.value.length - 1
    } else {
      selectedItem.value -= 1
    }
  }
})

const router = useRouter()
const route = useRoute()
const dataStore = useDataStore()
const tempStore = useTempStore()

//VARS
const type = route.params.type

const dataType = dataStore.dataTypes[type]
const canCreate = computed(() => {
  if (type === "filetags") {
    return true
  }

  if (type === "members") {
    return has("members-create") || has("customers-create")
  }
  return has(`${type}-create`)
})

const selectedColumns = ref(tempStore.columns[type] ? tempStore.columns[type] : dataType.templateColumns.filter(i => !i.disabledInTable))
const columns = computed(() => dataType.templateColumns.filter((column) => !column.disabledInTable && selectedColumns.value.find(i => i.key === column.key)))

const searchString = ref(tempStore.searchStrings[type] ||'')

const items = ref([])
const itemsMeta = ref({})
const selectedItem = ref(0)
const loading = ref(true)
const initialSetupDone = ref(false)
const pageLimit = ref(15)
const page = ref(tempStore.pages[type] || 1)

const sort = ref({
  column: dataType.sortColumn || "created_at",
  direction: 'desc'
})
const sorting = computed({
  get: () => [{
    id: sort.value.column,
    desc: sort.value.direction === 'desc'
  }],
  set: (value) => {
    const nextSort = Array.isArray(value) ? value[0] : undefined
    if (!nextSort?.id) {
      return
    }

    sort.value = {
      column: nextSort.id,
      direction: nextSort.desc ? 'desc' : 'asc'
    }
    setupPage()
  }
})

const columnsToFilter = ref({})

const showMobileFilter = ref(false)
let lastSearchRequestId = 0


//Functions

function resetMobileFilters() {
  if (!itemsMeta.value?.distinctValues) return

  Object.keys(itemsMeta.value.distinctValues).forEach(key => {
    columnsToFilter.value[key] = [...itemsMeta.value.distinctValues[key]]
    tempStore.clearFilter(type, key)
  })

  showMobileFilter.value = false
  setupPage()
}

function applyMobileFilters() {
  Object.keys(columnsToFilter.value).forEach(key => {
    const selected = columnsToFilter.value[key]
    const available = itemsMeta.value?.distinctValues?.[key] || []

    if (!Array.isArray(selected) || selected.length === 0 || selected.length === available.length) {
      tempStore.clearFilter(type, key)
      columnsToFilter.value[key] = [...available]
      return
    }

    tempStore.modifyFilter(type, key, selected)
  })

  showMobileFilter.value = false
  setupPage()
}

const clearSearchString = () => {
  tempStore.clearSearchString(type)
  searchString.value = ''
  setupPage()
}

const performSearch = async () => {
  tempStore.modifySearchString(type, searchString.value)
  changePage(1,true)
  setupPage()
}

const changePage = (number, noSetup = false) => {
  page.value = number
  tempStore.modifyPages(type, number)
  if(!noSetup) setupPage()
}



const changeSort = (column) => {
  if(sort.value.column === column) {
    sort.value.direction = sort.value.direction === 'desc' ? 'asc' : 'desc'
  } else {
    sort.value.direction = "asc"
    sort.value.column = column
  }

  changePage(1)
}

const isFiltered = computed(() => {
  if (!itemsMeta.value?.distinctValues) return false

  return Object.keys(columnsToFilter.value).some(key => {
    const allValues = itemsMeta.value.distinctValues[key]
    const selected = columnsToFilter.value[key]
    if (!allValues || !selected) return false
    return selected.length !== allValues.length
  })
})

const initializeDistinctFilters = () => {
  const distinctValues = itemsMeta.value?.distinctValues || {}
  const storedDomainFilters = tempStore.filters[type] || {}
  const normalizedStoredFilters = {}

  // Nur gültige, noch vorhandene Filterwerte aus dem TempStore übernehmen.
  Object.entries(distinctValues).forEach(([column, availableValues]) => {
    const available = Array.isArray(availableValues) ? availableValues : []
    const storedSelected = storedDomainFilters[column]

    if (!Array.isArray(storedSelected)) {
      columnsToFilter.value[column] = [...available]
      return
    }

    const selected = storedSelected.filter((value) => available.includes(value))
    const isFullSelection = selected.length === 0 || selected.length === available.length

    if (isFullSelection) {
      columnsToFilter.value[column] = [...available]
      return
    }

    columnsToFilter.value[column] = selected
    normalizedStoredFilters[column] = selected
  })

  // Persistiert bereinigte Filter nur einmalig bei der Initialisierung.
  tempStore.setFilters(type, normalizedStoredFilters)
}

const syncDistinctFiltersFromStore = () => {
  const distinctValues = itemsMeta.value?.distinctValues || {}
  const storedDomainFilters = tempStore.filters[type] || {}

  Object.entries(distinctValues).forEach(([column, availableValues]) => {
    const available = Array.isArray(availableValues) ? availableValues : []
    const storedSelected = storedDomainFilters[column]

    if (!Array.isArray(storedSelected) || storedSelected.length === 0) {
      columnsToFilter.value[column] = [...available]
      return
    }

    const selected = storedSelected.filter((value) => available.includes(value))
    if (selected.length === 0 || selected.length === available.length) {
      columnsToFilter.value[column] = [...available]
      tempStore.clearFilter(type, column)
      return
    }

    columnsToFilter.value[column] = selected
  })
}

//SETUP

const setupPage = async () => {
  const currentRequestId = ++lastSearchRequestId
  loading.value = true
  setPageLayout(platformIsNative ? "mobile" : "default")

  if (type === "tasks") {
    await navigateTo("/tasks")
    return
  }


  const filters = {
    archived:false
  }

  Object.entries(tempStore.filters[type] || {}).forEach(([column, selected]) => {
    if (Array.isArray(selected) && selected.length > 0) {
      filters[column] = selected
    }
  })


  const {data,meta} = await useEntities(type).selectPaginated({
    select: dataType.selectWithInformation || "*",
    filters: filters,
    sort: [{field: sort.value.column, direction: sort.value.direction}],
    page: page.value,
    limit: pageLimit.value,
    search: searchString.value,
    searchColumns: columns.value.map((i) => i.key),
    distinctColumns: dataType.templateColumns.filter(i => i.distinct).map(i => i.key),
  })

  // Verhindert Race Conditions beim schnellen Tippen:
  // Nur das Ergebnis des letzten Requests darf den State setzen.
  if (currentRequestId !== lastSearchRequestId) return

  items.value = data
  itemsMeta.value = meta
  if(!initialSetupDone.value){
    initializeDistinctFilters()
  } else {
    syncDistinctFiltersFromStore()
  }


  loading.value = false
  initialSetupDone.value = true

}

setupPage()

const handleFilterChange = async (action,column) => {
  if(action === 'reset') {
    columnsToFilter.value[column] = [...(itemsMeta.value.distinctValues?.[column] || [])]
    tempStore.clearFilter(type, column)
  } else if(action === 'change') {
    const selected = columnsToFilter.value[column]
    const available = itemsMeta.value.distinctValues?.[column] || []

    if (!Array.isArray(selected) || selected.length === 0 || selected.length === available.length) {
      tempStore.clearFilter(type, column)
      columnsToFilter.value[column] = [...available]
    } else {
      tempStore.modifyFilter(type,column,selected)
    }
  }
  setupPage()
}

const truncateValue = (value, maxLength) => {
  if (value === null || value === undefined || value === '') {
    return '\u00A0'
  }

  const stringValue = String(value)
  if (!maxLength || stringValue.length <= maxLength) {
    return stringValue
  }

  return `${stringValue.substring(0, maxLength)}...`
}

const getColumnDisplayValue = (column, row) => {
  const value = row[column.key]
  if (column.displayFunction) return column.displayFunction(value, row)
  return value
}

const getDistinctFilterItems = (columnKey) => {
  const column = dataType.templateColumns.find((item) => item.key === columnKey)

  return (itemsMeta.value?.distinctValues?.[columnKey] || []).map((value) => ({
    label: String(column?.displayFunction ? column.displayFunction(value) : value),
    value
  }))
}

const isDistinctFilterActive = (columnKey) => {
  const available = itemsMeta.value?.distinctValues?.[columnKey] || []
  const selected = columnsToFilter.value[columnKey] || []

  return selected.length > 0 && selected.length !== available.length
}



</script>

<template>
  <UDashboardNavbar :title="dataType.label" :badge="itemsMeta.total">
    <template #toggle>
      <div v-if="platformIsNative"></div>
    </template>
    <template #right v-if="!platformIsNative">
      <UTooltip :text="`${dataType.label} durchsuchen`">
        <UInput
            id="searchinput"
            v-model="searchString"
            icon="i-heroicons-funnel"
            autocomplete="off"
            placeholder="Suche..."
            class="hidden lg:block"
            @keydown.esc="$event.target.blur()"
            @keyup="performSearch"
            @change="performSearch"
        >
          <template #trailing>
            <UKbd value="/" />
          </template>
        </UInput>
      </UTooltip>
      <UTooltip text="Suche löschen" v-if="searchString.length > 0">
        <UButton
            icon="i-heroicons-x-mark"
            variant="outline"
            color="error"
            @click="clearSearchString()"

        />
      </UTooltip>


      <UTooltip :text="`${dataType.labelSingle} erstellen`">
        <UButton
            v-if="platform !== 'mobile' && canCreate/*&& useRole().checkRight(`${type}-create`)*/"
            @click="router.push(`/standardEntity/${type}/create`)"
            class="ml-3"
        >+ {{dataType.labelSingle}}</UButton>
      </UTooltip>

    </template>
  </UDashboardNavbar>


  <UDashboardToolbar v-if="!platformIsNative">
    <template #left>
      <UTooltip :text="`${dataType.label} pro Seite`">
        <USelectMenu
            :items="[{value:10},{value:15, disabled: itemsMeta.total < 15},{value:25, disabled: itemsMeta.total < 25},{value:50, disabled: itemsMeta.total < 50},{value:100, disabled: itemsMeta.total < 100},{value:250, disabled: itemsMeta.total < 250}]"
            v-model="pageLimit"
            value-key="value"
            label-key="value"
            @update:model-value="setupPage"
        />
      </UTooltip>
      <UPagination
          v-if="initialSetupDone && items.length > 0"
          :disabled="loading"
          v-model:page="page"
          :items-per-page="pageLimit"
          :total="itemsMeta.total"
          @update:page="changePage"
          :show-edges="true"
          first-icon="i-heroicons-chevron-double-left"
          last-icon="i-heroicons-chevron-double-right"
      />

    </template>

    <template #right>
      <UTooltip text="Angezeigte Spalten auswählen">
        <USelectMenu
            v-model="selectedColumns"
            icon="i-heroicons-adjustments-horizontal-solid"
            :items="dataType.templateColumns.filter(i => !i.disabledInTable)"
            multiple
            class="hidden lg:block"
            by="key"
            :color="selectedColumns.length !== dataType.templateColumns.filter(i => !i.disabledInTable).length ? 'primary' : 'white'"
            :content="{ width: 'min-w-max' }"
            @update:model-value="tempStore.modifyColumns(type, selectedColumns)"
        >
          <template #default>
            Spalten
          </template>
        </USelectMenu>
      </UTooltip>
    </template>
  </UDashboardToolbar>

  <div v-if="!platformIsNative">
    <UTable
        :loading="loading"
        v-model:sorting="sorting"
        v-if="dataType && columns && !loading"
        :data="items"
        :columns="normalizeTableColumns(columns)"
        class="w-full"
        style="height: 85dvh"
        :ui="{ divide: 'divide-gray-200 dark:divide-gray-800' }"
        :on-select="(row) => router.push(`/standardEntity/${type}/show/${row.original.id}`)"
    >
      <template
          v-for="column in dataType.templateColumns.filter(i => !i.disabledInTable)"
          v-slot:[`${column.key}-header`]="{row}">
        <InputGroup>
          <UTooltip v-if="column.sortable">
            <UButton
                variant="outline"
                @click="changeSort(column.key)"
                :color="sort.column === column.key ? 'primary' : 'white'"
                :icon="sort.column === column.key ? (sort.direction === 'asc' ? 'i-heroicons-arrow-up' : 'i-heroicons-arrow-down') : 'i-heroicons-arrows-up-down'"
            >

            </UButton>
          </UTooltip>
          <UTooltip
              v-if="column.distinct"
              :text="!columnsToFilter[column.key]?.length > 0 ? `Keine Einträge für ${column.label} verfügbar`  : `${column.label} Spalte nach Einträgen filtern`"
          >
            <USelectMenu
                class="min-w-0"
                :items="getDistinctFilterItems(column.key)"
                v-model="columnsToFilter[column.key]"
                multiple
                @update:model-value="handleFilterChange('change', column.key)"
                :search-input="{ placeholder: 'Suche...' }"
                value-key="value"
                label-key="label"
                :content="{ width: 'min-w-max' }"
                :disabled="getDistinctFilterItems(column.key).length === 0"
            >

              <template #empty>
                Keine Einträge in der Spalte {{column.label}}
              </template>
              <template #default="slotProps">
                <span class="inline-flex min-w-0 items-center">
                  <span class="truncate">{{ column.label }}</span>
                </span>
              </template>
            </USelectMenu>
          </UTooltip>
          <UButton
              variant="solid"
              color="white"
              v-else
              class="mr-2 truncate"
          >{{column.label}}</UButton>


          <UTooltip
              text="Filter zurücksetzen"
              v-if="columnsToFilter[column.key]?.length !== itemsMeta.distinctValues?.[column.key]?.length && column.distinct"
          >
            <UButton
                @click="handleFilterChange('reset',column.key)"
                variant="outline"
                color="error"
            >
              X
            </UButton>
          </UTooltip>


        </InputGroup>

      </template>
      <template #name-cell="{row}">
      <span
          v-if="row.original.id === items[selectedItem]?.id"
          class="block truncate text-primary-500 font-bold">
        <UTooltip
            :text="row.original.name"
        >
          <span class="block truncate">
            {{ truncateValue(row.original.name, dataType.templateColumns.find(i => i.key === "name")?.maxLength) }}
          </span>
        </UTooltip>      </span>
        <span v-else class="block truncate">
        <UTooltip
            :text="row.original.name"
        >
          <span class="block truncate">
            {{ truncateValue(row.original.name, dataType.templateColumns.find(i => i.key === "name")?.maxLength) }}
          </span>
        </UTooltip>
      </span>
      </template>
      <template #fullName-cell="{row}">
      <span
          v-if="row.original.id === items[selectedItem]?.id"
          class="block truncate text-primary-500 font-bold">{{ row.original.fullName }}
      </span>
        <span v-else class="block truncate">
        {{ row.original.fullName }}
      </span>
      </template>
      <template #licensePlate-cell="{row}">
      <span
          v-if="row.original.id === items[selectedItem]?.id"
          class="block truncate text-primary-500 font-bold">{{ row.original.licensePlate }}
      </span>
        <span v-else class="block truncate">
        {{ row.original.licensePlate }}
      </span>
      </template>
      <template
          v-for="column in dataType.templateColumns.filter(i => i.key !== 'name' && i.key !== 'fullName' && i.key !== 'licensePlate' && !i.disabledInTable)"
          v-slot:[`${column.key}-cell`]="{row}">
        <component v-if="column.component" :is="column.component" :row="row.original"></component>
        <span v-else-if="row.original[column.key]" class="block truncate">
        <UTooltip :text="String(getColumnDisplayValue(column, row.original))">
          <span class="block truncate">
            {{ `${truncateValue(getColumnDisplayValue(column, row.original), column.maxLength)}${column.unit ? ` ${column.unit}` : ''}` }}
          </span>
      </UTooltip>
      </span>

      </template>
      <template #empty>
        <TableEmptyState :label="`Keine ${dataType.label} anzuzeigen`" />
      </template>
    </UTable>
    <UProgress v-else animation="carousel" class="w-3/4 mx-auto mt-5"></UProgress>
  </div>
  <div v-else class="relative flex flex-col h-[calc(100dvh-80px)]">

    <!-- Mobile Searchbar (sticky top) -->
    <div class="p-2 bg-white dark:bg-gray-900 border-b sticky top-0 z-20">
      <InputGroup>
        <UInput
            v-model="searchString"
            icon="i-heroicons-magnifying-glass"
            placeholder="Suche..."
            @keyup="performSearch"
            @change="performSearch"
            class="w-full"
        />
        <UButton
            v-if="searchString.length > 0"
            icon="i-heroicons-x-mark"
            variant="ghost"
            color="error"
            @click="clearSearchString()"

        />
        <UButton
            icon="i-heroicons-funnel"
            variant="ghost"
            :color="isFiltered ? 'primary' : 'gray'"
            @click="showMobileFilter = true"
        />
      </InputGroup>

    </div>

    <!-- Scroll Area -->
    <UDashboardPanelContent class="flex-1 overflow-y-auto px-2 py-3 space-y-3 pb-[calc(8vh+env(safe-area-inset-bottom))] mobile-scroll-area">

      <UCard
          v-for="item in items"
          :key="item.id"
          class="p-4 rounded-xl shadow-sm border cursor-pointer active:scale-[0.98] transition"
          @click="router.push(`/standardEntity/${type}/show/${item.id}`)"
      >
        <div class="flex items-center justify-between mb-1">
          <p class="text-base font-semibold truncate text-primary-600">
            {{
              dataType.templateColumns.find(i => i.title)?.key
                  ? item[dataType.templateColumns.find(i => i.title).key]
                  : null
            }}
          </p>

          <UIcon
              name="i-heroicons-chevron-right-20-solid"
              class="text-gray-400 w-5 h-5 flex-shrink-0"
          />
        </div>

        <p class="text-sm text-gray-500 truncate">
          {{ dataType.numberRangeHolder ? item[dataType.numberRangeHolder] : null }}
        </p>

        <div
            v-for="secondInfo in dataType.templateColumns.filter(i => i.secondInfo)"
            :key="secondInfo.key"
            class="text-sm text-gray-400 truncate"
        >
          {{
            (secondInfo.secondInfoKey && item[secondInfo.key])
                ? item[secondInfo.key][secondInfo.secondInfoKey]
                : item[secondInfo.key]
          }}
        </div>
      </UCard>

      <div
          v-if="!loading && items.length > 0"
          class="p-4 bg-white dark:bg-gray-900 border-t flex items-center justify-center mt-4 rounded-xl"
      >
        <UPagination
            v-if="initialSetupDone && items.length > 0"
            :disabled="loading"
            v-model:page="page"
            :items-per-page="pageLimit"
            :total="itemsMeta.total"
            @update:page="changePage"
            :show-edges="true"
            first-icon="i-heroicons-chevron-double-left"
            last-icon="i-heroicons-chevron-double-right"
        />
      </div>

      <!-- Empty -->
      <UCard
          v-if="!loading && items.length === 0"
          class="mx-auto mt-10 p-6 text-center"
      >
        <TableEmptyState :label="`Keine ${dataType.label} anzuzeigen`" />
      </UCard>

      <div v-if="loading" class="mt-5">
        <UProgress animation="carousel" class="w-3/4 mx-auto"></UProgress>
      </div>

    </UDashboardPanelContent>
    <!-- Mobile Filter Slideover -->
    <USlideover
        v-model:open="showMobileFilter"
        side="bottom"
        :ui="{ width: '100%', height: 'auto', maxHeight: '90vh' }"
        class="pb-[env(safe-area-inset-bottom)]"
    >
      <template #body>
        <!-- Header -->
        <div class="p-4 border-b flex items-center justify-between flex-shrink-0">
          <h2 class="text-xl font-bold">Filter</h2>
          <UButton
              icon="i-heroicons-x-mark"
              variant="ghost"
              @click="showMobileFilter = false"
          />
        </div>

        <!-- Scrollable content -->
        <div class="flex-1 overflow-y-auto p-4 space-y-6">

          <div
              v-for="column in dataType.templateColumns.filter(c => c.distinct)"
              :key="column.key"
              class="space-y-2"
          >
            <p class="font-semibold">{{ column.label }}</p>

            <USelectMenu
                v-model="columnsToFilter[column.key]"
                :items="getDistinctFilterItems(column.key)"
                multiple
                value-key="value"
                label-key="label"
                :search-input="{ placeholder: `${column.label} filtern...` }"
                :filter-fields="['label']"
                placeholder="Auswählen…"
                :content="{ width: 'w-full' }"
                class="w-full"
            />
          </div>

        </div>

        <!-- Footer FIXED in card -->
        <div
            class="
          flex justify-between gap-3
          px-4 py-4 border-t flex-shrink-0
          bg-white dark:bg-gray-900
          rounded-b-2xl
        "
        >
          <UButton
              color="error"
              variant="outline"
              class="flex-1"
              @click="resetMobileFilters"
          >
            Zurücksetzen
          </UButton>

          <UButton
              color="primary"
              class="flex-1"
              @click="applyMobileFilters"
          >
            Anwenden
          </UButton>
        </div>
      </template>
    </USlideover>


  </div>
</template>

<style scoped>

</style>
