<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { ShoppingCart } from '@lucide/vue';
import { computed, onMounted, ref, watch } from 'vue';
import { toast } from 'vue-sonner';
import { apiFetch } from '@/lib/api';
import ConfirmDialog from '@/components/ConfirmDialog.vue';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    FieldGroup,
    FieldSet,
} from '@/components/ui/field';
import { formErrors } from '@/lib/form';
import { appendMediaToFormData, appendRootPhotosToFormData, createMediaUploadState } from '@/types/media';
import type { MediaItem, MediaUploadState } from '@/types/media';
import type { RestockCartItem, RestockProductCatalogItem } from '@/types/restock';
import RestockPosCartDetailDialog from './RestockPosCartDetailDialog.vue';
import RestockPosCartSummaryItems from './RestockPosCartSummaryItems.vue';
import RestockPosCatalogPanel from './RestockPosCatalogPanel.vue';
import RestockPosCheckoutSection from './RestockPosCheckoutSection.vue';
import { useRestockPosCart } from './useRestockPosCart';

const props = defineProps<{
    productCatalog: RestockProductCatalogItem[];
    initialData?: {
        notes: string;
        items: RestockCartItem[];
        photos?: MediaItem[];
    };
    draftItems?: RestockCartItem[];
    submitUrl: string;
    method: 'post' | 'put';
    submitLabel: string;
}>();

const isCreateMode = computed(() => props.method === 'post');
const photoState = ref<MediaUploadState>(createMediaUploadState());
const cartDetailOpen = ref(false);
const showDeleteConfirm = ref(false);
const itemIndexToDelete = ref<number | null>(null);

const form = useForm({
    notes: '',
    stock_type: 'good',
});

const {
    productSearch,
    cart,
    filteredProducts,
    subtotal,
    setCart,
    loadDraftItems,
    addProduct,
    removeItem,
    decreaseQty,
    updateQuantity,
    updateUnitPrice,
    getCartItem,
} = useRestockPosCart({
    productCatalog: () => props.productCatalog,
    isCreateMode: () => isCreateMode.value,
});

onMounted(() => {
    if (props.initialData) {
        form.notes = props.initialData.notes;
        form.stock_type = props.initialData.stock_type ?? 'good';
        photoState.value = createMediaUploadState(
            props.initialData.photos ?? [],
        );
        setCart(props.initialData.items);
    } else if (props.draftItems && props.draftItems.length > 0) {
        loadDraftItems(props.draftItems);
    }
});

function confirmRemoveItem(index: number) {
    itemIndexToDelete.value = index;
    showDeleteConfirm.value = true;
}

async function handleRemoveItem() {
    if (itemIndexToDelete.value === null) return;

    await removeItem(itemIndexToDelete.value);
    itemIndexToDelete.value = null;
    showDeleteConfirm.value = false;
}

function lineSubtotal(item: RestockCartItem): number {
    const qty = Number(item.quantity) || 0;
    return Math.round(qty * item.unit_price);
}

const total = computed(() => subtotal.value);

const isUploading = computed(() =>
    photoState.value.pendingUploads > 0,
);

function buildFormData(): FormData {
    const formData = new FormData();

    if (props.method === 'put') {
        formData.append('_method', 'PUT');
    }

    formData.append('notes', form.notes ?? '');
    formData.append('stock_type', form.stock_type ?? 'good');

    cart.value.forEach((item, index) => {
        formData.append(`items[${index}][product_variant_id]`, String(item.product_variant_id));
        formData.append(`items[${index}][quantity]`, item.quantity);
        formData.append(`items[${index}][unit_price]`, String(item.unit_price));
    });

    appendRootPhotosToFormData(formData, photoState.value);

    return formData;
}

function submit() {
    if (cart.value.length === 0) {
        toast.error('Tambahkan minimal satu produk.');
        return;
    }

    for (let i = 0; i < cart.value.length; i++) {
        const item = cart.value[i];
        if (!item.quantity || Number(item.quantity) <= 0) {
            toast.error(`Jumlah pada baris ke-${i + 1} harus lebih besar dari 0.`);
            return;
        }
        if (!item.unit_price || item.unit_price <= 0) {
            toast.error(`Harga satuan pada baris ke-${i + 1} harus lebih besar dari 0.`);
            return;
        }
    }

    const payload = buildFormData();

    form.transform(() => payload).post(props.submitUrl, {
        forceFormData: true,
        onError: (errors: Record<string, string>) => {
            if (errors.system) {
                toast.error(errors.system);
            } else {
                const firstError = Object.values(errors)[0];
                if (firstError) {
                    toast.error(firstError);
                } else {
                    toast.error('Perbaiki kesalahan pada form.');
                }
            }
        },
    });
}
</script>

<template>
    <div class="grid min-w-0 gap-4 xl:grid-cols-[1fr_380px]">
        <!-- Left Column: Product Catalog -->
        <div class="space-y-6">
            <RestockPosCatalogPanel
                :filtered-products="filteredProducts"
                :get-cart-item="getCartItem"
                :is-create-mode="isCreateMode"
                @add-product="addProduct"
                @decrease-qty="decreaseQty"
                @update:search="productSearch = $event"
            />
        </div>

        <!-- Right Column: Summary Panel (Ringkasan Restock) -->
        <Card class="h-fit xl:sticky xl:top-4">
            <CardHeader class="pb-3">
                <CardTitle class="flex items-center justify-between gap-2 text-base">
                    <span class="flex items-center gap-2">
                        <ShoppingCart class="size-4" />
                        Ringkasan Restock
                    </span>
                </CardTitle>
            </CardHeader>
            <CardContent>
                <form @submit.prevent="submit">
                    <FieldGroup>
                        <FieldSet class="grid gap-4">
                            <!-- Cart items -->
                            <RestockPosCartSummaryItems
                                :cart="cart"
                                :line-subtotal="lineSubtotal"
                                @remove="confirmRemoveItem"
                                @adjust-quantity="(index, delta) => {
                                    const item = cart[index];
                                    if (item) {
                                        const nextQty = (Number(item.quantity) || 0) + delta;
                                        if (nextQty <= 0) {
                                            confirmRemoveItem(index);
                                        } else {
                                            updateQuantity(item.product_variant_id, String(nextQty));
                                        }
                                    }
                                }"
                                @sync-quantity="(index) => {
                                    const item = cart[index];
                                    if (item) {
                                        updateQuantity(item.product_variant_id, item.quantity);
                                    }
                                }"
                            />

                            <!-- Totals, Notes, Photo, Submit -->
                            <RestockPosCheckoutSection
                                v-model:photo-state="photoState"
                                :form="form"
                                :subtotal="subtotal"
                                :total="total"
                                :cart-empty="cart.length === 0 || isUploading"
                                :submit-label="submitLabel"
                            />
                        </FieldSet>
                    </FieldGroup>
                </form>
            </CardContent>
        </Card>
    </div>

    <!-- Floating Cart button on mobile -->
    <button
        v-if="cart.length > 0"
        type="button"
        class="fixed top-50 right-6 z-50 flex size-14 items-center justify-center rounded-full bg-primary text-primary-foreground shadow-lg transition-transform hover:scale-105 active:scale-95 xl:hidden"
        @click="cartDetailOpen = true"
    >
        <ShoppingCart class="size-6" />
        <span class="absolute -right-1 -top-1 flex size-6 items-center justify-center rounded-full bg-destructive text-[11px] font-bold text-destructive-foreground">
            {{ cart.length > 99 ? '99+' : cart.length }}
        </span>
    </button>

    <!-- Cart detail dialog (mobile) -->
    <RestockPosCartDetailDialog
        v-model:open="cartDetailOpen"
        :cart="cart"
        :line-subtotal="lineSubtotal"
        :total="total"
        @remove="confirmRemoveItem"
        @adjust-quantity="(index, delta) => {
            const item = cart[index];
            if (item) {
                const nextQty = (Number(item.quantity) || 0) + delta;
                if (nextQty <= 0) {
                    confirmRemoveItem(index);
                } else {
                    updateQuantity(item.product_variant_id, String(nextQty));
                }
            }
        }"
        @set-quantity="(index, value) => {
            const item = cart[index];
            if (item) {
                updateQuantity(item.product_variant_id, value);
            }
        }"
    />

    <!-- Confirm deletion dialog -->
    <ConfirmDialog
        v-model:open="showDeleteConfirm"
        title="Hapus Item?"
        description="Apakah Anda yakin ingin menghapus item ini dari keranjang?"
        confirm-label="Hapus"
        cancel-label="Batal"
        destructive
        @confirm="handleRemoveItem"
    />
</template>
