<script setup lang="ts">

import { computed, ref, onMounted } from 'vue'
import { type Invoice } from '@/types'
import { newInvoice } from '@/types/index.d'
import axios from 'axios'
import AppLayout from '@/layouts/AppLayout.vue'
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, } from '@/components/ui/select'
import { Button } from '@/components/ui/button'
import DocumentTable from '@/components/documents/DocumentTable.vue'
import { ChevronLeft, ChevronRight, Plus, Search, Delete } from "lucide-vue-next"
import Fuse from 'fuse.js';
import { Input } from '@/components/ui/input'
import { toast } from 'vue-sonner'
import SelectSeparator from '@/components/ui/select/SelectSeparator.vue'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { Kbd, KbdGroup } from '@/components/ui/kbd'
import { statusBadgeLabels } from '@/components/ui/status-badge'
import AppHeader from '@/components/AppHeader.vue'
import InvoiceDialog from '@/components/documents/InvoiceDialog.vue'

// initial invoice data from inertia
interface Props {
    invoicesData: Invoice[];
}
const props = defineProps<Props>();
const invoicesData = ref(props.invoicesData || [])
const activeInvoice = ref<Invoice | undefined>(undefined)
const selectedYearIndex = ref(0)
const detailDialogOpen = ref(false)
const searchQuery = ref('')
const searchField = ref()

onMounted(async () => {
    // Load older invoices after initial page load
    try {
        const invoiceBeforeThisYearResponse = await axios.get('/api/invoices/summaryBeforeThisYear')
        invoicesData.value = invoicesData.value.concat(invoiceBeforeThisYearResponse.data as Invoice[])
    } catch (error) {
        console.error('Fehler beim Laden der Daten:', error)
    }

    let queryString = window.location.search
    let params = new URLSearchParams(queryString)
    if (params.get('action') == 'new') createInvoice()

    searchField.value = document.getElementById('search')
})

const years = computed((): number[] => {
    const allYears = invoicesData.value.map(invoice => {
        const date = new Date(invoice.invoiceDate);
        return date.getFullYear();
    })
    const uniqueYears = [...new Set(allYears.filter(year => !isNaN(year)))]
    uniqueYears.sort((a, b) => b - a)
    return uniqueYears
})

// Filter / search
const fuse = computed(() => {
    const options = {
        keys: [
            'billingData.companyName',
            {
                name: 'paymentStatus',
                getFn: (invoice: Invoice) => statusBadgeLabels[invoice.paymentStatus] || invoice.paymentStatus
            },
            'title',
            'nr'
        ],
        threshold: 0.3,
    }

    return new Fuse(invoicesData.value, options);
})

const filteredInvoices = computed(() => {
    if (!searchQuery.value) {
        return years.value[selectedYearIndex.value]
            ? invoicesData.value.filter(invoice => {
                const invoiceDate = new Date(invoice.invoiceDate);
                return invoiceDate.getFullYear() === years.value[selectedYearIndex.value];
            })
            : invoicesData.value;
    }

    return fuse.value.search(searchQuery.value)
        .map(result => result.item)
        .filter(invoice => {
            const invoiceDate = new Date(invoice.invoiceDate);
            return !years.value[selectedYearIndex.value] || invoiceDate.getFullYear() === years.value[selectedYearIndex.value];
        });
});

const createInvoice = () => {
    editInvoice(newInvoice())
}

const editInvoice = (invoice: Invoice) => {
    // make a deep copy, so the changes in the dialog won’t affect the data until saved
    activeInvoice.value = JSON.parse(JSON.stringify(invoice))
    detailDialogOpen.value = true
}

const onSaveInvoice = async (updatedInvoice: Invoice) => {
    // Update selectedYearIndex to ensure the new invoice is displayed
    const newInvoiceYear = new Date(updatedInvoice.invoiceDate).getFullYear();
    const currentYearIndex = years.value.findIndex(year => year === newInvoiceYear);
    if (currentYearIndex !== -1) {
        selectedYearIndex.value = currentYearIndex;
    }

    // Update table
    const index = invoicesData.value.findIndex(inv => inv.id === updatedInvoice.id);
    if (index !== -1) {
        invoicesData.value[index] = updatedInvoice;
    } else {
        invoicesData.value.push(updatedInvoice);
    }
}

const onDeleteInvoice = async (id: number) => {
    const index = invoicesData.value.findIndex(invoice => invoice.id === id)
    if (index !== -1) {
        invoicesData.value.splice(index, 1)
    }
}

</script>

<template>


    <!-- Function Header -->
    <AppLayout title="Rechnungen">

        <AppHeader>
            <!-- Year select -->
            <template #left>
                <Button variant="ghost" :disabled="selectedYearIndex >= (years.length - 1)"
                    @click="selectedYearIndex++">
                    <ChevronLeft />
                </Button>
                <Select size="sm" v-model="selectedYearIndex">
                    <SelectTrigger class="hover:bg-accent">
                        <SelectValue :placeholder="(new Date()).getFullYear().toString()"
                            :disabled="years.length < 1" />
                    </SelectTrigger>
                    <SelectContent>
                        <SelectGroup>
                            <SelectItem :value="null">
                                <SelectLabel>Alle</SelectLabel>
                            </SelectItem>
                            <SelectSeparator />
                            <SelectItem v-for="(year, index) in years" :value="index">
                                <SelectLabel>{{ year }}</SelectLabel>
                            </SelectItem>
                        </SelectGroup>
                    </SelectContent>
                </Select>
                <Button variant="ghost" @click="selectedYearIndex--" :disabled="selectedYearIndex <= 0">
                    <ChevronRight />
                </Button>
            </template>

            <!-- Search field -->
            <template #middle>
                <Input ref="search-field" id="search" type="text" placeholder="Filtern" class="px-8 bg-background"
                    v-model="searchQuery" />
                <span class="absolute start-0 inset-y-0 flex items-center justify-center px-2">
                    <Search class="size-4 text-muted-foreground" :stroke-width="1.5" />
                </span>
                <span class="absolute end-0 inset-y-0 flex items-center justify-center px-0 mr-1">
                    <Button :size="'sm'" :variant="'ghost'" @click="searchQuery = ''; searchField.focus()">
                        <Delete class="size-4 text-muted-foreground" :stroke-width="1.5" />
                    </Button>
                </span>
            </template>

            <!-- New button -->
            <template #right>
                <TooltipProvider>
                    <Tooltip>
                        <TooltipTrigger>
                            <Button size="sm" variant="action" @click="createInvoice">
                                <Plus />
                                Neu
                            </Button>
                        </TooltipTrigger>
                        <TooltipContent>
                            <span>Neue Rechnung anlegen</span>
                            <KbdGroup class="ml-2">
                                <Kbd class="visible-mac">⌘</Kbd>
                                <Kbd class="visible-pc">Ctrl</Kbd>
                                <Kbd>N</Kbd>
                            </KbdGroup>
                        </TooltipContent>
                    </Tooltip>
                </TooltipProvider>
            </template>

        </AppHeader>

        <!-- Invoice Table -->
        <DocumentTable :invoices="filteredInvoices" :onItemClicked="editInvoice" />

        <!-- Invoice detail dialog -->
        <InvoiceDialog :invoiceData="activeInvoice" v-model="detailDialogOpen" @save="onSaveInvoice"
            @delete="onDeleteInvoice" />

    </AppLayout>
</template>

<style>
@media print {
    #function-header {
        display: none;
    }
}
</style>