<script setup lang="ts">

import { ref, onMounted, computed, watch } from 'vue'
import AppLayout from '@/layouts/AppLayout.vue'
import AppHeader from '@/components/AppHeader.vue'
import { Address, Customer } from '@/types'
import { newCustomer } from '@/types/index.d'
import { bgColorForString } from '@/lib/utils'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { Input } from '@/components/ui/crm-input'
import { Button } from '@/components/ui/crm-button'
import { ButtonGroup } from '@/components/ui/button-group'
import { Delete, Globe, House, LayoutGrid, Mail, Phone, Plus, Rows3, Search, Smartphone } from "lucide-vue-next"
import Fuse from 'fuse.js';
import { getInitials } from '@/composables/useInitials';
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from '@/components/ui/card'
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogTitle, DialogClose } from "@/components/ui/dialog"
import DialogCloseButton from "@/components/DialogCloseButton/DialogCloseButton.vue"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { TooltipArrow } from 'reka-ui'
import CustomerDialog from '@/components/CustomerDialog.vue'
import { toast } from 'vue-sonner'
import { SocialIcon } from '@/components/ui/social-icon'
import { Kbd, KbdGroup } from '@/components/ui/kbd'

interface Props {
    customersData: Customer[];
}

const props = defineProps<Props>();

const customersData = ref([] as Customer[])
const searchQuery = ref('')
const searchField = ref()
const activeCustomer = ref<Customer | null>(null)
const detailDialogOpen = ref(false)
const phoneNumber = ref('')

onMounted(() => {
    customersData.value = props.customersData.toSorted((a, b) => (a.companyName ?? '').localeCompare(b.companyName ?? ''));
    searchField.value = document.getElementById('search')
    searchField.value.focus()
})

watch(activeCustomer, () => {
})

const fuse = computed(() => {
    return new Fuse(customersData.value, {
        keys: ['companyName', 'contacts.firstName', 'contacts.lastName'],
        threshold: 0.3
    });
})

const filteredCustomers = computed(() => {
    if (!searchQuery.value) {
        return customersData.value;
    }

    return fuse.value.search(searchQuery.value).map(result => result.item);
})

const createCustomer = () => {
    editCustomer(newCustomer())
}

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

const addressToClipbard = async function (companyName: string | null, address: Address | null, event: Event) {
    event.stopPropagation();
    try {
        let copy = '';
        if (companyName) copy += companyName + '\n'
        if (address) {
            copy +=
                address.lineOne + '\n' +
                (address.lineTwo ? address.lineTwo + '\n' : '') +
                address.postalCode + ' ' + address.city
        }
        await navigator.clipboard.writeText(copy)
        toast('Adresse kopiert', { duration: 2000 })
    } catch (notAllowedError: DOMException) {
        if (notAllowedError instanceof Error) {
            toast.error(notAllowedError.name, { description: notAllowedError.message })
        }
    }
}

const mail = (email: string, event: Event) => {
    event.stopPropagation();
    window.open('mailto:' + email, '_self')
}

const browse = (url: string, event: Event) => {
    event.stopPropagation();

    if (!/^https?:\/\//i.test(url)) {
        url = 'https://' + url;
    }

    try {
        const parsedUrl = new URL(url);
        if (!parsedUrl.hostname || parsedUrl.hostname === 'sers') {
            throw new Error('Ungültiger Hostname');
        }

        window.open(url, '_blank');
    } catch (e) {
        toast.error('Ungültige URL', {
            description: 'Die eingegebene URL ist nicht gültig.'
        });
    }
}

const showPhoneNumber = (number: string, event: Event | null) => {
    if (event) {
        event.preventDefault()
        event.stopPropagation();
        event.returnValue = true
    }

    phoneNumber.value = number
}

const closePhoneNumberDisplay = (event: Event | null) => {
    if (event) {
        event.preventDefault()
        event.stopPropagation();
        event.returnValue = true
    }

    phoneNumber.value = ''
}

const call = (number: string, event: Event) => {
    if (event) {
        event.preventDefault()
        event.stopPropagation();
        event.returnValue = true
    }
    window.open('tel:' + number, '_self')
}

</script>

<template>

    <AppLayout title="Kunden">

        <AppHeader>
            <!-- View buttons -->
            <template #left>
                <!-- <ButtonGroup aria-label="Button group">
                    <Button variant="pressed" size="sm">
                        <LayoutGrid stroke-width="1.5" />
                    </Button>
                    <Button variant="outline" size="sm">
                        <Rows3 stroke-width="1.5" />
                    </Button>
                </ButtonGroup> -->
            </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="createCustomer">
                                <Plus />
                                Neu
                            </Button>
                        </TooltipTrigger>
                        <TooltipContent>
                            <span>Neuen Kunden 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>


        <div class="columns-xs gap-6">

            <Card v-for="customer in filteredCustomers" :key="customer.id"
                class="relative mb-6 break-inside-avoid hover:border-slate-300 dark:hover:bg-neutral-800/90 dark:hover:border-neutral-600 overflow-clip"
                @click="editCustomer(customer)">

                <CardHeader v-if="customer.logo" class="z-0">
                    <img :src="'storage/uploads/customers/' + customer.logo" alt="Logo {{ customer.companyName }}"
                        class="max-h-8 max-w-[50%]" loading="lazy">
                </CardHeader>

                <CardContent class="flex justify-between gap-8 flex-col sm:flex-row pr-4 z-0">
                    <address class="not-italic">
                        <CardTitle>
                            {{ customer.companyName }}
                        </CardTitle>
                        <CardDescription class="mt-2">
                            {{ customer.billingAddress?.lineOne }}<br />
                            {{ customer.billingAddress?.lineTwo }}<br v-if="customer.billingAddress?.lineTwo" />
                            {{ customer.billingAddress?.postalCode }} {{ customer.billingAddress?.city }}
                        </CardDescription>
                    </address>

                    <div class="flex items-start">
                        <TooltipProvider>
                            <Tooltip v-if="customer.url">
                                <TooltipTrigger>
                                    <Button variant="ghost" size="sm" @click="browse(customer.url as string, $event)">
                                        <Globe stroke-width="1.5" />
                                    </Button>
                                </TooltipTrigger>
                                <TooltipContent>{{ customer.url }}</TooltipContent>
                            </Tooltip>
                            <Tooltip v-if="customer.phone">
                                <TooltipTrigger>
                                    <Button variant="ghost" size="sm"
                                        @click="showPhoneNumber(customer.phone as string, $event)">
                                        <Phone stroke-width="1.5" />
                                    </Button>
                                </TooltipTrigger>
                                <TooltipContent>{{ customer.phone }}</TooltipContent>
                            </Tooltip>
                            <Tooltip v-if="customer.billingAddress">
                                <TooltipTrigger>
                                    <Button variant="ghost" size="sm"
                                        @click="addressToClipbard(customer.companyName, customer.billingAddress as Address | null, $event)">
                                        <House stroke-width="1.5" />
                                    </Button>
                                </TooltipTrigger>
                                <TooltipContent>
                                    Adresse in Zwischenablage kopieren
                                </TooltipContent>
                            </Tooltip>
                        </TooltipProvider>
                    </div>
                </CardContent>

                <CardFooter v-if="customer.contacts.length > 0">
                    <TooltipProvider :delay-duration="0">

                        <Tooltip v-for="contact in customer.contacts">
                            <TooltipTrigger>
                                <Avatar class="size-14 border-2 border-background -mr-2">
                                    <AvatarImage v-if="contact.avatar"
                                        :src="'/storage/uploads/contacts/' + contact.avatar" loading="lazy"
                                        class="object-cover" />
                                    <AvatarFallback
                                        :class="bgColorForString(getInitials(contact.firstName + ' ' + contact.lastName))">
                                        {{ getInitials(contact.firstName + ' ' + contact.lastName) }}
                                    </AvatarFallback>
                                </Avatar>
                            </TooltipTrigger>
                            <TooltipContent class="p-4 -mr-2" :side-offset="-1">
                                <p class="font-bold">
                                    <span v-if="contact.academicTitle">{{ contact.academicTitle }}</span>
                                    <span>{{ contact.firstName + ' ' + contact.lastName }}</span>
                                </p>
                                <p v-if="contact.jobTitle" class="text-muted-foreground">{{ contact.jobTitle }}</p>

                                <ButtonGroup class="mt-4">
                                    <!-- E-mail -->
                                    <Button size="sm" v-if="contact.email"
                                        @click="mail(contact.email as string, $event)">
                                        <Mail stroke-width="1.5" @click="" />
                                    </Button>
                                    <!-- Phone -->
                                    <Button size="sm" v-if="contact.phone"
                                        @click="showPhoneNumber(contact.phone as string, $event)">
                                        <Phone stroke-width="1.5" @click="" />
                                    </Button>
                                    <!-- Mobile phone -->
                                    <Button size="sm" v-if="contact.mobilePhone"
                                        @click="showPhoneNumber(contact.mobilePhone as string, $event)">
                                        <Smartphone stroke-width="1.5" @click="" />
                                    </Button>
                                    <!-- Online accounts -->
                                    <Button size="sm" v-for="account in contact.onlineAccounts"
                                        @click="browse(account.url as string, $event)">
                                        <SocialIcon :variant="account.platform" />
                                    </Button>
                                </ButtonGroup>
                                <TooltipArrow :height="8" :width="16"
                                    class="fill-popover drop-shadow-(--shadow-arrow) stroke-[0.5px] stroke-border -mt-px" />
                            </TooltipContent>
                        </Tooltip>

                    </TooltipProvider>
                </CardFooter>
            </Card>

        </div>

        <!-- Invoice detail dialog -->
        <CustomerDialog :customerData="activeCustomer" v-model="detailDialogOpen" @save="" @delete="" />

        <!-- Phone number display -->
        <Dialog :open="phoneNumber !== ''">

            <DialogContent class="w-fit sm:max-w-auto sm:p-8 md:p-9 gap-6 lg:ps-12 lg:gap-9 xl:p-14 xl:gap-12"
                @escapeKeyDown="closePhoneNumberDisplay" @interactOutside="closePhoneNumberDisplay">
                <DialogTitle class="screen-reader-only hidden">
                    <h1>{{ phoneNumber }}</h1>
                </DialogTitle>
                <DialogDescription class="screen-reader-only hidden">Anrufen</DialogDescription>

                <div
                    class="transition-all text-md sm:text-2xl md:text-3xl lg:text-6xl xl:text-8xl whitespace-nowrap proportional-nums lg:tracking-wide font-medium">
                    {{ phoneNumber }}</div>

                <DialogFooter>
                    <DialogClose as-child>
                        <Button @click="closePhoneNumberDisplay">
                            Schließen
                        </Button>
                        <Button @click="call(phoneNumber, $event)" variant="action">
                            <Phone stroke-width="1.5" />
                            Anrufen
                        </Button>
                    </DialogClose>
                </DialogFooter>

                <DialogClose as-child>
                    <DialogCloseButton @click="closePhoneNumberDisplay" />
                </DialogClose>
            </DialogContent>
        </Dialog>

    </AppLayout>
</template>

<style></style>