<script setup lang="ts">
import CreateButton from '@/components/button/CreateButton.vue';
import { Card, CardContent } from '@/components/ui/card';
import { useCan } from '@/composables/useCan';
import {
    useDataTableQuery,
    useDataTableQuerySync,
} from '@/composables/useDataTableQuery';
import {
    getPaperSizeLabel,
    useThermalPrinter,
} from '@/composables/useThermalPrinter';
import AdminLayout from '@/layouts/AdminLayout.vue';
import type { PaperSize } from '@/lib/thermal-printer/types';
import type { PaginatedOrders } from '@/types/order';
import { Head, usePage } from '@inertiajs/vue3';
import { computed, onMounted, ref, watch } from 'vue';
import { toast } from 'vue-sonner';
import { index, create } from '@/routes/admin/manage/orders';
import ThermalPrinterConnectButton from '@/components/order/ThermalPrinterConnectButton.vue';
import OrderGroupedTable from './table/OrderGroupedTable.vue';

const props = defineProps<{
    orders: PaginatedOrders;
    filters: {
        search: string;
        sort?: string;
        direction?: 'asc' | 'desc';
    };
}>();

const { can } = useCan();
const page = usePage();
const { isConnected, printOrderReceipt, tryReconnect } = useThermalPrinter();
const search = ref(props.filters.search ?? '');

const { setSearch, resetFilters, syncFromServer } = useDataTableQuery({
    url: index.url(),
    initial: { ...props.filters },
});

useDataTableQuerySync(() => props.filters, syncFromServer);

const tablePagination = computed(() => ({
    currentPage: props.orders.current_page,
    perPage: props.orders.per_page,
    lastPage: props.orders.last_page,
    total: props.orders.total,
}));

const firstItem = computed(() =>
    props.orders.data.length > 0
        ? (props.orders.current_page - 1) * props.orders.per_page + 1
        : 0,
);

watch(search, (value) => {
    setSearch(value);
});

watch(
    () => props.filters.search,
    (value) => {
        search.value = value ?? '';
    },
);

onMounted(async () => {
    const urlParams = new URLSearchParams(window.location.search);

    if (!urlParams.has('print') || props.orders.data.length === 0) {
        return;
    }

    const paperSize = (urlParams.get('paper_size') || '80mm') as PaperSize;
    const order = props.orders.data[0];

    window.history.replaceState({}, '', window.location.pathname);

    if (!isConnected.value) {
        const restored = await tryReconnect();

        if (!restored) {
            toast.error('Printer belum terhubung. Struk tidak dapat dicetak.');

            return;
        }
    }

    try {
        await printOrderReceipt({
            order,
            paperSize,
            storeName: page.props.name as string,
            storeAddress: (page.props.address as string) ?? '',
        });

        toast.success(
            `Struk ${order.order_number} dikirim ke printer ${getPaperSizeLabel(paperSize)}.`,
        );
    } catch (error) {
        const message =
            error instanceof Error
                ? error.message
                : 'Gagal mencetak struk pesanan.';

        toast.error(message);
    }
});
</script>

<template>
    <Head title="Pesanan" />

    <AdminLayout>
        <div
            class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between"
        >
            <div class="space-y-1">
                <h2 class="text-2xl font-bold tracking-tight">Pesanan</h2>
            </div>

            <div
                class="flex shrink-0 items-center gap-2 self-start sm:self-center"
                v-if="can('orders.create')"
            >
                <ThermalPrinterConnectButton />

                <CreateButton :href="create.url()" />
            </div>
        </div>

        <Card class="min-w-0">
            <CardContent class="min-w-0">
                <OrderGroupedTable
                    v-model:search="search"
                    :orders="orders.data"
                    :first-item="firstItem"
                    :pagination="tablePagination"
                    :pagination-links="orders.links"
                    @filters-reset="resetFilters"
                />
            </CardContent>
        </Card>
    </AdminLayout>
</template>
