<!-- TODO: Mengenfeld Komma als decimal point -->
<!-- TODO: Enter in LineItem = neue Zeile -->
<script setup lang="ts">

import { ref, watch, HTMLAttributes, onUpdated, onMounted } from 'vue'
import draggable from 'vuedraggable';
import { cn, toCurrency } from '@/lib/utils';
import { LineItem } from '@/types';
import { newLineItem } from '@/types/index.d'
import { Table, TableCell, TableFooter, TableHead, TableHeader, TableRow, } from '@/components/ui/table';
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"
import { NumberField, NumberFieldContent, NumberFieldDecrement, NumberFieldIncrement, NumberFieldInput, } from '@/components/ui/number-field'
import { Input } from '@/components/ui/input';
import { Loader2, GripVertical, Trash2, Plus, TextSelect } from 'lucide-vue-next';
import Button from '../ui/button/Button.vue';
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, } from '@/components/ui/empty'
import NumberInput from '../ui/number-input/NumberInput.vue';
import { GrowingTextarea } from '../ui/growing-textarea';

const props = defineProps<{
  isLoading?: boolean,
  lineItems: LineItem[] | undefined,
  stickyTop: number | string,
  class?: HTMLAttributes['class']
}>()

const emit = defineEmits<{
  (e: 'update:lineItems', value: LineItem[]): void
}>()

const isLoading = ref(props.isLoading || false)
const units = ref(['Stück', 'Stunden', 'Tage', 'pauschal'])
const items = ref((props.lineItems ?? []).slice().sort(function (a, b) { return a.position - b.position })) // items only uses props.lineItems as the initial value;

onUpdated(() => {
  if (isLoading.value) isLoading.value = false
})

watch(items, (newItems) => {
  if (isLoading.value) return

  emit('update:lineItems', newItems)
}, { deep: true })

watch(() => props.lineItems, (newLineItems) => {
  isLoading.value = (newLineItems?.length || 0) > 0
  items.value = (newLineItems ?? []).slice().sort(function (a, b) { return a.position - b.position })
}, { deep: true, once: true })

const newItem = (isSection: boolean) => {
  let item = newLineItem(isSection)
  item.position = getNextPosition(items.value.length, isSection)
  items.value.push(item)
}

const getNextPosition = (index: number, isSection: boolean) => {
  let lastPosition = (index == 0) ? 0 : items.value.at(index - 1)?.position ?? 0
  let nextInteger = (lastPosition == Math.ceil(lastPosition)) ? lastPosition + 1 : Math.ceil(lastPosition)

  // item: next integer
  // sections: middle between last element and next integer
  return isSection ?
    lastPosition + (nextInteger - lastPosition) / 2
    : nextInteger
}

const deleteItem = (lineItem: LineItem) => {
  const index = items.value.indexOf(lineItem)
  if (index > -1) {
    items.value.splice(index, 1)
  }
  recalculatePositions()
}

const recalculatePositions = () => {
  for (let i = 0; i < items.value.length; i++) {
    items.value[i].position = getNextPosition(i, items.value[i].isSection)
  }
}

</script>

<template>

  <div :class="cn(props.class)">

    <div class="backdrop-blur-sm bg-background/90 sticky z-1 pt-8"
      :style="'top: calc(var(--spacing) * ' + (props.stickyTop ? props.stickyTop : 0) + ');'">
      <Table class="table-fixed">
        <TableHeader>
          <TableRow class="hover:bg-transparent dark:hover:bg-transparent border-b-1">
            <TableHead class="w-6 px-0"></TableHead>
            <TableHead class="w-8 px-0 text-center">Pos.</TableHead>
            <TableHead>Posten</TableHead>
            <TableHead class="w-1/8">Einh.</TableHead>
            <TableHead class="w-20 text-center">Menge</TableHead>
            <TableHead class="w-1/8 text-right pr-5">Einzel</TableHead>
            <TableHead class="w-1/8 text-right">Total</TableHead>
            <TableHead class="w-8"></TableHead>
          </TableRow>
        </TableHeader>
      </Table>
    </div>

    <Table :class="{ 'opacity-100!': !isLoading && items.length >= 1 }"
      class="table-fixed transition-opacity opacity-0 duration-300">

      <draggable v-model="items" tag="tbody" item-key="position" handle=".handle" ghostClass="ghost"
        @end="recalculatePositions">
        <template #item="{ element }">

          <TableRow v-if="element.isSection">
            <TableCell class="handle px-1 cursor-move w-6">
              <GripVertical :size="18" stroke-width="1.5" class="text-muted-foreground" />
            </TableCell>

            <!-- Posten -->
            <TableCell colspan="6" class="pt-6">
              <Input v-model="element.title" placeholder="Titel"
                class="font-bold text-base! p-1 h-7! m-0 -mb-1 bg-transparent dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66 border-none hover:border-1 dark:hover:border-1 placeholder:text-muted-foreground/30 shadow-none" />
              <GrowingTextarea v-model="element.description" placeholder="Text"
                class="font-light bg-transparent dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66 py-0 px-1 m-0 border-none shadow-none" />
            </TableCell>


            <!-- Buttons -->
            <TableCell class="w-8 text-right px-1">
              <Button variant="ghost" size="sm" @click="deleteItem(element)"
                class="has-[>svg]:px-1 text-muted-foreground hover:text-destructive">
                <Trash2 :size="18" stroke-width="1.5"/>
              </Button>
            </TableCell>
          </TableRow>

          <TableRow v-else>
            <TableCell class="handle px-1 cursor-move w-6">
              <GripVertical :size="18" stroke-width="1.5" class="text-muted-foreground" />
            </TableCell>

            <!-- Pos. -->
            <TableCell class="text-center position w-8">{{ element.position }}</TableCell>

            <!-- Posten -->
            <TableCell>
              <Input v-model="element.title" placeholder="Posten"
                class="font-bold p-1 h-7! m-0 -mb-1 bg-transparent dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66 border-none hover:border-1 dark:hover:border-1 placeholder:text-muted-foreground/30 shadow-none" />
              <GrowingTextarea v-model="element.description" placeholder="Beschreibung"
                class="text-muted-foreground font-light m-0 bg-transparent dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66 py-0 px-1 m-0 border-none shadow-none" />

            </TableCell>

            <!-- Einh. -->
            <TableCell class="w-1/8 text-center">
              <Select v-model="element.unit">
                <SelectTrigger
                  class="shadow-none bg-transparent p-1 h-7! dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66 border-none w-full">
                  <SelectValue placeholder="Einheit" />
                </SelectTrigger>
                <SelectContent>
                  <SelectGroup>
                    <SelectItem v-for="unit in units" :value="unit">
                      {{ unit }}
                    </SelectItem>
                  </SelectGroup>
                </SelectContent>
              </Select>
            </TableCell>

            <!-- Anz. -->
            <TableCell class="w-20 text-center">
              <NumberField v-model="element.quantity" :step="0.5" :format-options="{}">
                <NumberFieldContent>
                  <NumberFieldDecrement
                    class="text-muted-foreground p-1 h-7! bg-transparent dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66" />
                  <NumberFieldInput
                    class="h-6 border-none p-1 h-7! bg-transparent dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66" />
                  <NumberFieldIncrement
                    class="text-muted-foreground p-1 h-7! bg-transparent dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66" />
                </NumberFieldContent>
              </NumberField>
            </TableCell>

            <!-- Preis -->
            <TableCell class="w-1/8 text-right tabular-nums">
              <NumberInput v-model="element.price"
                class="bg-transparent p-1 h-7! dark:bg-transparent hover:bg-background/66 dark:hover:bg-background/66 rounded shadow-none!" />
            </TableCell>

            <!-- Total -->
            <TableCell class="w-1/8 text-right tabular-nums font-bold">{{ toCurrency(element.price * element.quantity)
            }}
            </TableCell>

            <!-- Buttons -->
            <TableCell class="w-8 text-right px-1">
              <Button variant="ghost" size="sm" @click="deleteItem(element)"
                class="has-[>svg]:px-1 text-muted-foreground hover:text-destructive">
                <Trash2 :size="18" stroke-width="1.5"/>
              </Button>
            </TableCell>
          </TableRow>

        </template>
      </draggable>

      <TableFooter v-if="items.length >= 1" class="bg-transparent">
        <TableRow class="hover:bg-transparent dark:hover:bg-transparent">
          <TableCell colspan="8">
            <div class="flex gap-2 justify-center">
              <Button class="mt-4" variant="ghost" @click="newItem(true)">
                <Plus /> Neuer Abschnitt
              </Button>
              <Button class="mt-4" variant="ghost" @click="newItem(false)">
                <Plus /> Neue Zeile
              </Button>
            </div>
          </TableCell>
        </TableRow>
      </TableFooter>

    </Table>

    <Loader2 v-if="isLoading" class="mx-auto mt-8 h-6 w-6 animate-spin text-muted-foreground" stroke-width="1.5" />

    <Empty v-else-if="items.length < 1" class="py-8!">
      <EmptyHeader>
        <EmptyMedia variant="icon">
          <TextSelect class="text-muted-foreground" stroke-width="1.5" />
        </EmptyMedia>
        <EmptyTitle>Diese Rechnung ist leer</EmptyTitle>
        <EmptyDescription>Erstelle hier deinen ersten Posten</EmptyDescription>
      </EmptyHeader>
      <div class="flex gap-2">
        <Button variant="action" @click="newItem(true)">
          <Plus stroke-width="1.5" /> Neuer Abschnitt
        </Button>
        <Button variant="action" @click="newItem(false)">
          <Plus stroke-width="1.5" /> Neue Zeile
        </Button>
      </div>
    </Empty>

  </div>

</template>

<style scoped>
tr.ghost {
  background: var(--color-muted);
  color: var(--color-muted-foreground);
}

tr.ghost .position {
  color: transparent;
}

tr.ghost .handle svg {
  stroke: transparent;
  fill: transparent;
}
</style>