<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { computed, ref } from 'vue';
import { toast } from 'vue-sonner';
import { RowDeleteAction, RowDetailAction, RowEditAction, RowStatusAction } from '@/components/button';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import OrderPrintButton from '@/components/order/OrderPrintButton.vue';
import { Button } from '@/components/ui/button';
import { useCan } from '@/composables/useCan';
import {
    orderStatusActionIcon,
    orderStatusTransitionConfirmDescription,
} from '@/constants/order-status';
import { show, edit, destroy, transition_status } from '@/routes/admin/manage/orders';
import type { OrderListItem, OrderStatusAction } from '@/types/order';

const props = defineProps<{
    order: OrderListItem;
}>();

const { can } = useCan();

const statusConfirmOpen = ref(false);
const statusProcessing = ref(false);
const pendingAction = ref<OrderStatusAction | null>(null);

const availableActions = computed(() => props.order.available_actions ?? []);

const canEdit = computed(() => props.order.is_editable && can('orders.update'));
const canDelete = computed(() => can('orders.delete'));

function canPerformAction(action: OrderStatusAction): boolean {
    return can(action.permission);
}

function statusConfirmDescription(action: OrderStatusAction): string {
    return orderStatusTransitionConfirmDescription(action.status, props.order.order_number);
}

function openStatusConfirm(action: OrderStatusAction) {
    pendingAction.value = action;
    statusConfirmOpen.value = true;
}

function transitionStatus() {
    if (!pendingAction.value) {
        return;
    }

    statusProcessing.value = true;

    router.post(transition_status.url(props.order.id), {
        status: pendingAction.value.status,
    }, {
        preserveScroll: true,
        onSuccess: () => {
            statusConfirmOpen.value = false;
            pendingAction.value = null;
        },
        onError: (errors: any) => {
            if (errors.system) {
                toast.error(errors.system);
            }
        },
        onFinish: () => {
            statusProcessing.value = false;
        },
    });
}
</script>

<template>
    <div class="flex flex-wrap items-center justify-end gap-1">
        <OrderPrintButton :order="order" />

        <template v-for="action in availableActions" :key="action.status">
            <RowStatusAction v-if="action.icon_only && canPerformAction(action)" :icon="orderStatusActionIcon(action.status)"
                :label="action.label" :destructive="action.destructive" @click="openStatusConfirm(action)" />

            <Button v-else-if="canPerformAction(action)" size="sm" :variant="action.destructive ? 'outline' : 'default'"
                :class="action.destructive ? 'text-destructive hover:text-destructive' : ''"
                @click="openStatusConfirm(action)">
                <component :is="orderStatusActionIcon(action.status)" class="size-3.5" />
                {{ action.label }}
            </Button>
        </template>

        <RowDetailAction :href="show.url(order.id)" tooltip="Detail" />

        <RowEditAction v-if="canEdit" :href="edit.url(order.id)" />

        <template v-if="canDelete">
            <RowDeleteAction :action-url="destroy.url(order.id)" title="Hapus pesanan?"
                :description="`Pesanan ${order.order_number} akan dihapus.${order.is_editable ? ' Stok produk akan dikembalikan.' : ''}`"
                error-message="Gagal menghapus pesanan." />
        </template>
    </div>

    <ConfirmDialog v-model:open="statusConfirmOpen"
        :title="pendingAction ? `${pendingAction.label} pesanan?` : 'Ubah status pesanan?'"
        :description="pendingAction ? statusConfirmDescription(pendingAction) : ''"
        :confirm-label="pendingAction?.label ?? 'Konfirmasi'" cancel-label="Batal"
        :destructive="pendingAction?.destructive ?? false" :loading="statusProcessing" @confirm="transitionStatus" />
</template>
