<script setup lang="ts">
import { useForm } from '@inertiajs/vue3';
import { ShoppingCart } from '@lucide/vue';
import { computed, ref, watch } from 'vue';
import { toast } from 'vue-sonner';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
    FieldGroup,
    FieldSet,
} from '@/components/ui/field';
import { parseRupiah } from '@/lib/rupiah';
import { appendRootPhotosToFormData, createMediaUploadState } from '@/types/media';
import type { MediaItem, MediaUploadState } from '@/types/media';
import type { PurchaseCartItem, PurchaseCatalogItem, SelectOption } from '@/types/purchase';
import type { RawMaterialPrice } from '@/types/raw-material';
import PurchasePosAddVariantDialog from './PurchasePosAddVariantDialog.vue';
import PurchasePosCartDetailDialog from './PurchasePosCartDetailDialog.vue';
import PurchasePosCartSummaryItems from './PurchasePosCartSummaryItems.vue';
import PurchasePosCatalogPanel from './PurchasePosCatalogPanel.vue';
import PurchasePosCheckoutSection from './PurchasePosCheckoutSection.vue';
import PurchasePosMetadataFields from './PurchasePosMetadataFields.vue';
import { usePurchasePosCart } from './usePurchasePosCart';

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 cartDetailOpen = ref(false);
const addVariantOpen = ref(false);
const addVariantRawMaterial = ref<PurchaseCatalogItem | null>(null);
const photoState = ref<MediaUploadState>(createMediaUploadState());

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

const {
    search,
    cart,
    filteredCatalog,
    subtotal,
    setCart,
    loadDraftItems,
    getCartItem,
    lineSubtotal,
    addToCart,
    removeFromCart,
    adjustQuantity,
    syncCartItemQuantity,
    decreasePriceQty,
} = usePurchasePosCart({
    catalog: () => props.catalog,
    isCreateMode: () => isCreateMode.value,
});

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));

function populateForm() {
    if (!props.initialData) {
        return;
    }

    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] : [],
    );
    setCart(props.initialData.items);
}

watch(() => props.initialData, populateForm, { immediate: true });
loadDraftItems(props.draftItems ?? []);

function openAddVariant(rawMaterial: PurchaseCatalogItem) {
    addVariantRawMaterial.value = rawMaterial;
    addVariantOpen.value = true;
}

function handleVariantAdded(rawMaterialId: number, newPrice: RawMaterialPrice) {
    const rawMaterial = props.catalog.find((rm) => rm.id === rawMaterialId);

    if (rawMaterial) {
        rawMaterial.prices.push(newPrice);
    }
}

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);

    if (props.method === 'put') {
        cart.value.forEach((item, index) => {
            formData.append(`items[${index}][raw_material_price_id]`, String(item.raw_material_price_id));
            formData.append(`items[${index}][quantity]`, item.quantity);
        });
    }

    appendRootPhotosToFormData(formData, photoState.value);

    return formData;
}

function submit() {
    if (cart.value.length === 0) {
        toast.error('Tambahkan minimal satu bahan baku ke keranjang.');

        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);
            }
        },
    });
}
</script>

<template>
    <div class="grid gap-4 xl:grid-cols-[1fr_380px]">
        <PurchasePosCatalogPanel
            v-model:search="search"
            :filtered-catalog="filteredCatalog"
            :get-cart-item="getCartItem"
            @add-to-cart="addToCart"
            @decrease-qty="decreasePriceQty"
            @add-variant="openAddVariant"
        />

        <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>
                    <button
                        v-if="cart.length > 0"
                        type="button"
                        class="text-xs font-normal text-primary underline underline-offset-2 hover:text-primary/80"
                        @click="cartDetailOpen = true"
                    >
                        Lihat Detail
                    </button>
                </CardTitle>
            </CardHeader>
            <CardContent>
                <form @submit.prevent="submit">
                    <FieldGroup>
                        <FieldSet class="grid gap-4">
                            <PurchasePosMetadataFields :form="form" :suppliers="suppliers" />

                            <PurchasePosCartSummaryItems
                                :cart="cart"
                                :line-subtotal="lineSubtotal"
                                @remove="removeFromCart"
                                @adjust-quantity="adjustQuantity"
                                @sync-quantity="syncCartItemQuantity"
                            />

                            <PurchasePosCheckoutSection
                                v-model:photo-state="photoState"
                                :form="form"
                                :subtotal="subtotal"
                                :total="total"
                                :cart-empty="cart.length === 0"
                                :submit-label="submitLabel"
                            />
                        </FieldSet>
                    </FieldGroup>
                </form>
            </CardContent>
        </Card>
    </div>

    <PurchasePosAddVariantDialog
        v-model:open="addVariantOpen"
        :raw-material="addVariantRawMaterial"
        @variant-added="handleVariantAdded"
    />

    <PurchasePosCartDetailDialog
        v-model:open="cartDetailOpen"
        :cart="cart"
        :line-subtotal="lineSubtotal"
        :total="total"
    />
</template>
