<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { Check, Package, Plus, Search, ShoppingCart } from '@lucide/vue';
import { computed, onMounted, onUnmounted, 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 { Input } from '@/components/ui/input';
import {
    FieldError,
    FieldGroup,
    FieldSet,
} from '@/components/ui/field';
import { useVariantList } from '@/composables/useVariantList';
import { formErrors } from '@/lib/form';
import { parseRupiah } from '@/lib/rupiah';
import RawMaterialInfoSection from '@/pages/admin/master/raw-materials/form/RawMaterialInfoSection.vue';
import RawMaterialSharedPriceSection from '@/pages/admin/master/raw-materials/form/RawMaterialSharedPriceSection.vue';
import RawMaterialVariantSection from '@/pages/admin/master/raw-materials/form/RawMaterialVariantSection.vue';
import { appendMediaToFormData, appendRootPhotosToFormData, createMediaUploadState } from '@/types/media';
import type { MediaItem, MediaUploadState } from '@/types/media';
import type { PurchaseCartItem, PurchaseCatalogItem, SelectOption } from '@/types/purchase';
import type { RawMaterialPriceFormItem } from '@/types/raw-material';
import PurchasePosCartDetailDialog from './PurchasePosCartDetailDialog.vue';
import PurchasePosCartSummaryItems from './PurchasePosCartSummaryItems.vue';
import PurchasePosCheckoutSection from './PurchasePosCheckoutSection.vue';
import PurchasePosMetadataFields from './PurchasePosMetadataFields.vue';

const props = defineProps<{
    suppliers: SelectOption[];
    catalog: PurchaseCatalogItem[];
    initialData?: {
        supplier_id: string;
        discount: string;
        shipping_cost: string;
        notes: string;
        items: PurchaseCartItem[];
        photos?: MediaItem | null;
    };
    draftItems?: PurchaseCartItem[];
    submitUrl: string;
    method: 'post' | 'put';
    submitLabel: string;
}>();

const isCreateMode = computed(() => props.method === 'post');
const photoState = ref<MediaUploadState>(createMediaUploadState());
const savingStates = ref<Record<string, boolean>>({});

const cartDetailOpen = ref(false);

// Confirmation Dialog state
const showDeleteConfirm = ref(false);
const priceToDelete = ref<string | null>(null);

const form = useForm({
    supplier_id: '',
    discount: '',
    shipping_cost: '',
    notes: '',
    name: '',
    unit: '',
});

const units = [
    { value: 'yard', label: 'Yard' },
    { value: 'meter', label: 'Meter' },
    { value: 'kilogram', label: 'Kilogram' },
];

function createClientId(): string {
    return `price-${crypto.randomUUID()}`;
}

const {
    items: prices,
    removeItem: removePrice,
    setField: setPriceField,
    appendToFormData,
    itemErrors: priceErrorsList,
} = useVariantList<RawMaterialPriceFormItem>(
    'prices',
    () => ({
        client_id: createClientId(),
        variant: '',
        price: '',
        stock: '0',
        media: createMediaUploadState(),
    }),
    () => {
        if (props.initialData && props.initialData.items.length > 0) {
            return props.initialData.items.map((item) => ({
                client_id: createClientId(),
                id: item.raw_material_price_id,
                variant: item.variant ?? '',
                price: String(item.unit_price ?? ''),
                stock: String(item.quantity ?? '0'),
                media: createMediaUploadState(item.images ?? []),
            }));
        }

        if (props.draftItems && props.draftItems.length > 0) {
            return props.draftItems.map((item) => ({
                client_id: createClientId(),
                id: item.raw_material_price_id,
                variant: item.variant ?? '',
                price: String(item.unit_price ?? ''),
                stock: String(item.quantity ?? '0'),
                media: createMediaUploadState(item.images ?? []),
            }));
        }

        return [];
    }
);

const manualUseSamePrice = ref<boolean | null>(null);

const useSamePrice = computed(() => {
    if (manualUseSamePrice.value !== null) {
        return manualUseSamePrice.value;
    }
    return prices.value.length <= 1 || allPricesHaveSameValue();
});

function allPricesHaveSameValue(): boolean {
    if (prices.value.length <= 1) {
        return true;
    }
    const first = prices.value[0].price.trim();
    return prices.value.every((item) => item.price.trim() === first);
}

function toggleUseSamePrice(checked: boolean) {
    manualUseSamePrice.value = checked;

    if (!checked || !prices.value[0]) {
        return;
    }

    const sourcePrice = prices.value[0].price;
    prices.value = prices.value.map((price) => ({ ...price, price: sourcePrice }));
}

function applyPriceToAllVariants(sourceClientId: string) {
    const source = prices.value.find((price) => price.client_id === sourceClientId);

    if (!source) {
        return;
    }

    prices.value = prices.value.map((price) => ({ ...price, price: source.price }));
}

function addPrice() {
    prices.value.forEach((price) => savePriceToDb(price));

    const newPrice: RawMaterialPriceFormItem = {
        client_id: createClientId(),
        variant: '',
        price: '',
        stock: '0',
        media: createMediaUploadState(),
    };

    if (useSamePrice.value && prices.value[0]) {
        newPrice.price = prices.value[0].price;
    }

    prices.value = [...prices.value, newPrice];
}

function setPriceValue(clientId: string, value: string) {
    setPriceField(clientId, 'price', value);
}

function setSharedPrice(value: string) {
    prices.value = prices.value.map((price) => ({ ...price, price: value }));
}

// Reactively map the prices array to the CartItem structure expected by components
const cart = computed(() => {
    return prices.value.map((price) => {
        let unitAbbr = 'yd';
        const u = form.unit?.toLowerCase();
        if (u === 'meter') unitAbbr = 'm';
        else if (u === 'kilogram') unitAbbr = 'kg';

        return {
            raw_material_price_id: price.id || 0,
            raw_material_name: form.name || 'Bahan Baku',
            variant: price.variant || 'Varian Baru',
            unit_abbreviation: unitAbbr,
            quantity: price.stock,
            unit_price: Number(parseRupiah(price.price)) || 0,
            images: [], // not used in cart detail displays
        };
    });
});

function confirmRemovePrice(clientId: string) {
    priceToDelete.value = clientId;
    showDeleteConfirm.value = true;
}

async function handleRemovePrice() {
    if (!priceToDelete.value) return;

    const clientId = priceToDelete.value;
    const idx = prices.value.findIndex((p) => p.client_id === clientId);
    if (idx !== -1) {
        const price = prices.value[idx];
        if (price.id) {
            try {
                await apiFetch(`/admin/manage/purchases/draft-items/${price.id}`, {
                    method: 'DELETE',
                });
            } catch (error) {
                console.error(error);
            }
        }
        removePrice(clientId, true);
    }

    priceToDelete.value = null;
    showDeleteConfirm.value = false;
}

function removeFromCart(index: number) {
    const price = prices.value[index];
    if (price) {
        confirmRemovePrice(price.client_id);
    }
}

function adjustQuantity(index: number, delta: number) {
    const price = prices.value[index];
    if (price) {
        const nextQty = (Number(price.stock) || 0) + delta;
        if (nextQty <= 0) {
            confirmRemovePrice(price.client_id);
        } else {
            price.stock = String(nextQty);
            debouncedSave(price);
        }
    }
}

function syncCartInput(index: number) {
    const cartItem = cart.value[index];
    const price = prices.value[index];
    if (price && cartItem) {
        price.stock = cartItem.quantity;
    }
}

function syncCartItemQuantity(index: number) {
    const price = prices.value[index];
    const cartItem = cart.value[index];
    if (price && cartItem) {
        price.stock = cartItem.quantity;
        debouncedSave(price);
    }
}

function setCartItemQuantity(index: number, value: string) {
    const price = prices.value[index];
    if (price) {
        price.stock = value;
        debouncedSave(price);
    }
}

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

// Debounce helper to prevent spamming database saves while typing
function debounce<T extends (...args: any[]) => any>(fn: T, delay: number): (...args: Parameters<T>) => void {
    let timeoutId: ReturnType<typeof setTimeout> | null = null;
    return (...args: Parameters<T>) => {
        if (timeoutId) clearTimeout(timeoutId);
        timeoutId = setTimeout(() => {
            fn(...args);
        }, delay);
    };
}

// Auto-save variant to DB logic
async function savePriceToDb(price: typeof prices.value[0]) {
    if (
        !form.name.trim() ||
        !form.unit ||
        !price.variant.trim() ||
        !price.stock ||
        Number(price.stock) <= 0 ||
        !price.price ||
        Number(parseRupiah(price.price)) <= 0
    ) {
        return;
    }

    if (savingStates.value[price.client_id]) return;

    savingStates.value[price.client_id] = true;

    try {
        if (!price.id) {
            const formData = new FormData();
            formData.append('name', form.name.trim());
            formData.append('unit', form.unit);
            formData.append('variant', price.variant.trim());
            formData.append('price', parseRupiah(price.price));
            formData.append('quantity', price.stock);

            if (price.media.newFiles.length > 0) {
                price.media.newFiles.forEach((file) => {
                    formData.append('photos[]', file);
                });
            }

            if (price.media.newFileS3Keys.length > 0) {
                price.media.newFileS3Keys.forEach((key) => {
                    formData.append('s3_keys[]', key);
                });
            }

            const response = await apiFetch<{ item: any }>(
                '/admin/manage/purchases/draft-items/new-raw-material',
                {
                    method: 'POST',
                    body: formData,
                }
            );

            price.id = response.item.raw_material_price_id;

            if (response.item.images?.length > 0) {
                price.media.existing = response.item.images;
                price.media.newFiles = [];
                price.media.newFileS3Keys = [];
            }
        } else {
            const hasNewPhotos = price.media.newFiles.length > 0 || price.media.newFileS3Keys.length > 0;

            if (hasNewPhotos) {
                const formData = new FormData();
                formData.append('raw_material_price_id', String(price.id));
                formData.append('quantity', String(Number(price.stock) || 0));

                price.media.newFiles.forEach((file) => {
                    formData.append('photos[]', file);
                });

                price.media.newFileS3Keys.forEach((key) => {
                    formData.append('s3_keys[]', key);
                });

                const response = await apiFetch<{ item: any }>(
                    '/admin/manage/purchases/draft-items',
                    {
                        method: 'POST',
                        body: formData,
                    }
                );

                if (response.item.images?.length > 0) {
                    price.media.existing = response.item.images;
                    price.media.newFiles = [];
                    price.media.newFileS3Keys = [];
                }
            } else {
                await apiFetch(
                    '/admin/manage/purchases/draft-items',
                    {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({
                            raw_material_price_id: price.id,
                            quantity: Number(price.stock) || 0,
                        }),
                    }
                );
            }
        }
    } catch (error) {
        console.error(error);
    } finally {
        savingStates.value[price.client_id] = false;
    }
}

const debouncedSave = debounce(async (price: typeof prices.value[0]) => {
    await savePriceToDb(price);
}, 600);

const prevUploadCount = ref(0);

watch(
    () => prices.value.reduce((sum, p) => sum + (p.media.pendingUploads || 0), 0),
    (current, old) => {
        prevUploadCount.value = old ?? 0;

        if (old > 0 && current === 0) {
            prices.value.forEach((price) => {
                if (price.media.newFiles.length > 0 || price.media.newFileS3Keys.length > 0) {
                    debouncedSave(price);
                }
            });
        }
    },
);

// Variant master form event interceptors
function handleUpdateVariant(clientId: string, value: string) {
    setPriceField(clientId, 'variant', value);
    const price = prices.value.find((p) => p.client_id === clientId);
    if (price) debouncedSave(price);
}

function handleUpdateStock(clientId: string, value: string) {
    setPriceField(clientId, 'stock', value);
    const price = prices.value.find((p) => p.client_id === clientId);
    if (price) debouncedSave(price);
}

function handleUpdatePrice(clientId: string, value: string) {
    setPriceValue(clientId, value);
    const price = prices.value.find((p) => p.client_id === clientId);
    if (price) debouncedSave(price);
}

function handleApplyPriceToAll(clientId: string) {
    applyPriceToAllVariants(clientId);
    prices.value.forEach((price) => debouncedSave(price));
}

function handleToggleUseSamePrice(checked: boolean) {
    toggleUseSamePrice(checked);
    prices.value.forEach((price) => debouncedSave(price));
}

async function handleSetSharedPrice(value: string) {
    setSharedPrice(value);
    prices.value.forEach((price) => debouncedSave(price));
}

// Autocomplete from props.catalog
const catalogMaterialNames = computed(() => {
    return [...new Set(props.catalog.map((c) => c.name))];
});

// Search existing raw materials from catalog
const materialSearch = ref('');
const materialSearchResults = ref<Array<{
    priceId: number;
    rawMaterialId: number;
    name: string;
    unit: string;
    variant: string;
    price: number;
    priceFormatted: string;
    stockFormatted: string;
    images: MediaItem[];
}>>([]);

const searchContainerRef = ref<HTMLElement | null>(null);
const isExistingMaterial = ref(false);
const selectedMaterialId = ref<number | null>(null);

const selectedMaterialVariants = computed(() => {
    if (!selectedMaterialId.value) return [];
    const mat = props.catalog.find((r) => r.id === selectedMaterialId.value);
    return mat ? mat.prices.map((p) => ({ value: p.variant, label: p.variant })) : [];
});

watch(() => prices.value.length, (len) => {
    if (len === 0) {
        isExistingMaterial.value = false;
        selectedMaterialId.value = null;
        materialSearch.value = '';
        materialSearchResults.value = [];
    }
});

function onDocumentClick(e: MouseEvent) {
    if (searchContainerRef.value && !searchContainerRef.value.contains(e.target as Node)) {
        materialSearchResults.value = [];
    }
}

onMounted(() => document.addEventListener('click', onDocumentClick));
onUnmounted(() => document.removeEventListener('click', onDocumentClick));

function onMaterialSearch() {
    const keyword = materialSearch.value.trim().toLowerCase();

    const results: typeof materialSearchResults.value[0][] = [];

    if (selectedMaterialId.value !== null) {
        const mat = props.catalog.find((r) => r.id === selectedMaterialId.value);
        if (mat) {
            for (const price of mat.prices) {
                if (!keyword || price.variant.toLowerCase().includes(keyword)) {
                    results.push({
                        priceId: price.id,
                        rawMaterialId: mat.id,
                        name: mat.name,
                        unit: mat.unit,
                        variant: price.variant,
                        price: price.price,
                        priceFormatted: price.price_formatted,
                        stockFormatted: price.stock_formatted,
                        images: price.images ?? [],
                    });
                }
            }
        }
    } else {
        if (!keyword) {
            materialSearchResults.value = [];
            return;
        }

        for (const rm of props.catalog) {
            for (const price of rm.prices) {
                if (rm.name.toLowerCase().includes(keyword) || price.variant.toLowerCase().includes(keyword)) {
                    results.push({
                        priceId: price.id,
                        rawMaterialId: rm.id,
                        name: rm.name,
                        unit: rm.unit,
                        variant: price.variant,
                        price: price.price,
                        priceFormatted: price.price_formatted,
                        stockFormatted: price.stock_formatted,
                        images: price.images ?? [],
                    });
                }
            }
        }
    }
    materialSearchResults.value = results.slice(0, 20);
}

function selectExistingMaterial(result: (typeof materialSearchResults.value)[0]) {
    if (selectedMaterialId.value !== result.rawMaterialId) {
        isExistingMaterial.value = true;
        selectedMaterialId.value = result.rawMaterialId;
        form.name = result.name;
        form.unit = result.unit;
    }

    prices.value.push({
        client_id: createClientId(),
        id: result.priceId,
        variant: result.variant,
        price: String(result.price),
        stock: '0',
        media: createMediaUploadState(result.images),
    });

    toast.success(`"${result.name} → ${result.variant}" ditambahkan ke keranjang.`);

    const lastPrice = prices.value[prices.value.length - 1];
    if (lastPrice) {
        debouncedSave(lastPrice);
    }

    onMaterialSearch();
}

function isInCart(priceId: number): boolean {
    return prices.value.some((p) => p.id === priceId);
}

function onMaterialNameInput() {
    isExistingMaterial.value = false;
    selectedMaterialId.value = null;
    const matched = props.catalog.find(
        (c) => c.name.toLowerCase() === form.name.trim().toLowerCase()
    );
    if (matched) {
        form.unit = matched.unit;
    }
    // Save any newly valid variants
    prices.value.forEach((price) => debouncedSave(price));
}

function getVariantsForMaterial() {
    const matched = props.catalog.find(
        (c) => c.name.toLowerCase() === form.name.trim().toLowerCase()
    );
    return matched ? matched.prices.map((p) => p.variant) : [];
}

function onVariantInput(price: typeof prices.value[0]) {
    const matchedMaterial = props.catalog.find(
        (c) => c.name.toLowerCase() === form.name.trim().toLowerCase()
    );
    if (matchedMaterial) {
        const matchedPrice = matchedMaterial.prices.find(
            (p) => p.variant.toLowerCase() === price.variant.trim().toLowerCase()
        );
        if (matchedPrice) {
            price.id = matchedPrice.id;
            price.price = String(matchedPrice.price);
            debouncedSave(price);
        }
    }
}

// Map frontend validation errors from RawMaterialForm style to items.* backend array style
function priceErrors(form: any, clientId: string, field: string): string[] {
    const index = prices.value.findIndex((p) => p.client_id === clientId);
    if (index === -1) return [];

    let mappedField = field;
    if (field === 'stock') mappedField = 'quantity';
    else if (field === 'images') mappedField = 'photos';

    return formErrors(form, `items.${index}.${mappedField}`);
}

// Calculations
const subtotal = computed(() => {
    return prices.value.reduce((sum, price) => {
        const qty = Number(price.stock) || 0;
        const pr = Number(parseRupiah(price.price)) || 0;
        return sum + Math.round(qty * pr);
    }, 0);
});

const discountAmount = computed(() => Number(parseRupiah(form.discount)) || 0);
const shippingAmount = computed(() => Number(parseRupiah(form.shipping_cost)) || 0);
const total = computed(() => Math.max(subtotal.value - discountAmount.value + shippingAmount.value, 0));

const isUploading = computed(() =>
    prices.value.some((p) => p.media.pendingUploads > 0)
);

function populateForm() {
    manualUseSamePrice.value = null;
    if (props.initialData) {
        form.supplier_id = props.initialData.supplier_id;
        form.discount = props.initialData.discount;
        form.shipping_cost = props.initialData.shipping_cost ?? '0';
        form.notes = props.initialData.notes;
        photoState.value = createMediaUploadState(
            props.initialData.photos ? [props.initialData.photos] : []
        );

        if (props.initialData.items.length > 0) {
            const firstItem = props.initialData.items[0];
            form.name = firstItem.raw_material_name || '';
            
            let unitVal = 'yard';
            const ua = firstItem.unit_abbreviation?.toLowerCase();
            if (ua === 'm' || ua === 'meter') unitVal = 'meter';
            else if (ua === 'kg' || ua === 'kilogram') unitVal = 'kilogram';
            else if (ua === 'yd' || ua === 'yard') unitVal = 'yard';
            form.unit = unitVal;
        }

        prices.value = props.initialData.items.map((item) => ({
            client_id: createClientId(),
            id: item.raw_material_price_id,
            variant: item.variant ?? item.variant_name ?? '',
            price: String(item.unit_price ?? ''),
            stock: String(item.quantity ?? '0'),
            media: createMediaUploadState(item.images ?? []),
        }));
    } else if (props.draftItems && props.draftItems.length > 0) {
        const firstItem = props.draftItems[0];
        form.name = firstItem.raw_material_name || '';
        
        let unitVal = 'yard';
        const ua = firstItem.unit_abbreviation?.toLowerCase();
        if (ua === 'm' || ua === 'meter') unitVal = 'meter';
        else if (ua === 'kg' || ua === 'kilogram') unitVal = 'kilogram';
        else if (ua === 'yd' || ua === 'yard') unitVal = 'yard';
        form.unit = unitVal;

        prices.value = props.draftItems.map((item) => ({
            client_id: createClientId(),
            id: item.raw_material_price_id,
            variant: item.variant ?? item.variant_name ?? '',
            price: String(item.unit_price ?? ''),
            stock: String(item.quantity ?? '0'),
            media: createMediaUploadState(item.images ?? []),
        }));
    } else {
        form.name = '';
        form.unit = 'yard';
        prices.value = [];
    }
}

watch(() => props.initialData, populateForm, { immediate: true });

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

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

    formData.append('supplier_id', form.supplier_id);
    formData.append('discount', parseRupiah(form.discount));
    formData.append('shipping_cost', parseRupiah(form.shipping_cost));
    formData.append('notes', form.notes);

    prices.value.forEach((price, index) => {
        if (price.id) {
            formData.append(`items[${index}][raw_material_price_id]`, String(price.id));
        }
        formData.append(`items[${index}][name]`, form.name.trim());
        formData.append(`items[${index}][unit]`, form.unit);
        formData.append(`items[${index}][variant]`, price.variant.trim());
        formData.append(`items[${index}][quantity]`, price.stock);
        formData.append(`items[${index}][price]`, parseRupiah(price.price));
        appendMediaToFormData(formData, `items[${index}]`, price.media);
    });

    appendRootPhotosToFormData(formData, photoState.value);

    return formData;
}

function submit() {
    if (!form.name.trim()) {
        toast.error('Nama bahan baku wajib diisi.');
        return;
    }
    if (!form.unit) {
        toast.error('Satuan bahan baku wajib dipilih.');
        return;
    }
    if (prices.value.length === 0) {
        toast.error('Tambahkan minimal satu varian.');
        return;
    }

    for (let i = 0; i < prices.value.length; i++) {
        const p = prices.value[i];
        if (!p.variant.trim()) {
            toast.error(`Nama varian pada baris ke-${i + 1} wajib diisi.`);
            return;
        }
        if (!p.stock || Number(p.stock) <= 0) {
            toast.error(`Jumlah beli pada baris ke-${i + 1} harus lebih besar dari 0.`);
            return;
        }
        const parsedPrice = Number(parseRupiah(p.price)) || 0;
        if (parsedPrice <= 0) {
            toast.error(`Harga beli pada baris ke-${i + 1} harus lebih besar dari 0.`);
            return;
        }
        const imageCount = p.media.existing.length - p.media.removeIds.length + p.media.newFiles.length;
        if (imageCount <= 0) {
            toast.error(`Foto varian pada baris ke-${i + 1} wajib diunggah.`);
            return;
        }
    }

    if (!form.supplier_id) {
        toast.error('Pilih supplier terlebih dahulu.');
        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>
    <datalist id="catalog-names">
        <option v-for="name in catalogMaterialNames" :key="name" :value="name" />
    </datalist>

    <div class="grid min-w-0 gap-4 xl:grid-cols-[1fr_380px]">
        <!-- Left Column: Form Info & Variants (styled exactly like RawMaterialForm.vue) -->
        <div class="space-y-6">
            <!-- Search existing raw materials -->
            <div ref="searchContainerRef" class="relative">
                <div class="relative">
                    <Search class="absolute top-1/2 left-3 size-4 -translate-y-1/2 text-muted-foreground" />
                    <Input v-model="materialSearch"
                        :placeholder="selectedMaterialId ? 'Cari varian dari ' + (props.catalog.find(r => r.id === selectedMaterialId)?.name ?? '') + '...' : 'Cari bahan baku yang sudah ada...'"
                        class="pl-9" @input="onMaterialSearch" />
                </div>

                <div v-if="materialSearchResults.length > 0" class="absolute left-0 right-0 z-50 mt-1 max-h-60 overflow-y-auto rounded-md border bg-popover shadow-md">
                    <div v-for="result in materialSearchResults" :key="result.priceId"
                        class="flex items-center gap-3 px-3 py-2 text-sm"
                        :class="isInCart(result.priceId)
                            ? 'cursor-default opacity-60'
                            : 'cursor-pointer hover:bg-accent'"
                        @click="!isInCart(result.priceId) && selectExistingMaterial(result)"
                    >
                        <div class="size-10 shrink-0 overflow-hidden rounded border bg-muted/30">
                            <img v-if="result.images.length > 0"
                                :src="result.images[0].thumb_url"
                                :alt="result.variant"
                                class="size-full object-cover" />
                            <div v-else class="flex size-full items-center justify-center text-muted-foreground">
                                <Package class="size-4 opacity-40" />
                            </div>
                        </div>
                        <div class="min-w-0 flex-1">
                            <p class="truncate font-medium">{{ selectedMaterialId ? '' : result.name + ' → ' }}{{ result.variant }}</p>
                            <p class="text-xs text-muted-foreground">
                                Stok: {{ result.stockFormatted }} | Harga: {{ result.priceFormatted }}
                            </p>
                        </div>
                        <Button v-if="isInCart(result.priceId)" type="button" variant="ghost" size="icon-sm" disabled>
                            <Check class="size-3.5 text-primary" />
                        </Button>
                        <Button v-else type="button" variant="outline" size="icon-sm">
                            <Plus class="size-3.5" />
                        </Button>
                    </div>
                </div>
            </div>

            <RawMaterialInfoSection :form="form" :units="units" method="post" :disabled="isExistingMaterial" />

            <RawMaterialSharedPriceSection :form="form" :prices="prices" :use-same-price="useSamePrice"
                @toggle-use-same-price="handleToggleUseSamePrice" @set-shared-price="handleSetSharedPrice" />

            <RawMaterialVariantSection v-for="(price, index) in prices" :key="price.client_id" :form="form"
                :price="price" :index="index" :total-prices="prices.length" :use-same-price="useSamePrice"
                :price-errors="(clientId, field) => priceErrors(form, clientId, field)"
                :variant-options="selectedMaterialVariants"
                @remove="confirmRemovePrice(price.client_id)" @apply-price-to-all="handleApplyPriceToAll(price.client_id)"
                @update:variant="handleUpdateVariant(price.client_id, $event)"
                @update:stock="handleUpdateStock(price.client_id, $event)"
                @update:price="handleUpdatePrice(price.client_id, $event)" />

            <FieldError :errors="formErrors(form, 'items')" />

            <div class="flex justify-start">
                <Button type="button" variant="outline" class="flex items-center gap-2" @click="addPrice">
                    <Plus class="size-4" />
                    Tambah Varian
                </Button>
            </div>
        </div>

        <!-- Right Column: Summary Panel (Ringkasan Belanja) -->
        <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 Belanja
                    </span>
                </CardTitle>
            </CardHeader>
            <CardContent>
                <form @submit.prevent="submit">
                    <FieldGroup>
                        <FieldSet class="grid gap-4">
                            <!-- Supplier metadata input fields -->
                            <PurchasePosMetadataFields :form="form" :suppliers="suppliers" />

                            <!-- List of selected items in the summary card (original PurchasePosCartSummaryItems) -->
                            <PurchasePosCartSummaryItems
                                :cart="cart"
                                :line-subtotal="lineSubtotal"
                                @remove="removeFromCart"
                                @adjust-quantity="adjustQuantity"
                                @sync-quantity="syncCartItemQuantity"
                                @sync-quantity-input="syncCartInput"
                            />

                            <!-- Totals, Discount, Shipping, Notes, Photo dropzone, Submit -->
                            <PurchasePosCheckoutSection
                                v-model:photo-state="photoState"
                                :form="form"
                                :subtotal="subtotal"
                                :total="total"
                                :cart-empty="prices.length === 0 || !form.name.trim() || isUploading"
                                :submit-label="submitLabel"
                            />
                        </FieldSet>
                    </FieldGroup>
                </form>
            </CardContent>
        </Card>
    </div>



    <!-- Original Cart detail dialog -->
    <PurchasePosCartDetailDialog
        v-model:open="cartDetailOpen"
        :cart="cart"
        :line-subtotal="lineSubtotal"
        :total="total"
        @remove="removeFromCart"
        @adjust-quantity="adjustQuantity"
        @set-quantity="setCartItemQuantity"
    />

    <!-- Original 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>

    <!-- Confirm deletion dialog (same as in RawMaterialForm.vue) -->
    <ConfirmDialog
        v-model:open="showDeleteConfirm"
        title="Hapus Varian?"
        description="Apakah Anda yakin ingin menghapus varian ini? Tindakan ini tidak dapat dibatalkan."
        confirm-label="Hapus"
        cancel-label="Batal"
        destructive
        @confirm="handleRemovePrice"
    />
</template>
