import { computed, ref, toValue } from 'vue';
import type { MaybeRefOrGetter } from 'vue';
import { toast } from 'vue-sonner';
import { apiFetch } from '@/lib/api';
import draft_items from '@/routes/admin/manage/restocks/draft_items';
import type {
    RestockCartItem,
    RestockProductCatalogItem,
} from '@/types/restock';

export type RestockCatalogVariant = RestockProductCatalogItem['variants'][number] & { harga_modal: number };

export function useRestockPosCart(options: {
    productCatalog: MaybeRefOrGetter<RestockProductCatalogItem[]>;
    isCreateMode: MaybeRefOrGetter<boolean>;
}) {
    const productSearch = ref('');
    const cart = ref<RestockCartItem[]>([]);

    function setCart(items: RestockCartItem[]) {
        cart.value = items.map((item) => ({ ...item }));
    }

    function loadDraftItems(items: RestockCartItem[]) {
        if (!toValue(options.isCreateMode)) {
            return;
        }

        if (items.length > 0) {
            cart.value = items.map((item) => ({ ...item }));
        }
    }

    const filteredProducts = computed(() => {
        const keyword = productSearch.value.trim().toLowerCase();
        const catalog = toValue(options.productCatalog);

        if (!keyword) {
            return catalog;
        }

        return catalog.filter(
            (product) =>
                product.name.toLowerCase().includes(keyword)
                || product.variants.some((variant) => variant.name.toLowerCase().includes(keyword)),
        );
    });

    const subtotal = computed(() =>
        cart.value.reduce((sum, item) => {
            const qty = Number(item.quantity) || 0;
            return sum + Math.round(qty * item.unit_price);
        }, 0),
    );

    function upsertCartItem(item: RestockCartItem) {
        const index = cart.value.findIndex(
            (cartItem) => cartItem.product_variant_id === item.product_variant_id,
        );

        if (index === -1) {
            cart.value.push({ ...item });

            return;
        }

        cart.value[index] = { ...item };
    }

    async function syncDraftItem(variantId: number, quantity: string, unitPrice: number) {
        const { item } = await apiFetch<{ item: RestockCartItem }>(draft_items.store.url(), {
            method: 'POST',
            body: JSON.stringify({
                product_variant_id: variantId,
                quantity,
                unit_price: unitPrice,
            }),
        });

        upsertCartItem(item);
    }

    function getCartItem(variantId: number): RestockCartItem | undefined {
        return cart.value.find((item) => item.product_variant_id === variantId);
    }

    function addProduct(product: RestockProductCatalogItem, variant: RestockCatalogVariant) {
        const existing = cart.value.find(
            (item) => item.product_variant_id === variant.id,
        );

        if (existing) {
            existing.quantity = String((Number(existing.quantity) || 0) + 1);
            trySyncToBackend(existing);
            return;
        }

        cart.value.push({
            product_variant_id: variant.id,
            product_name: product.name,
            variant_name: variant.name,
            stock: variant.stock,
            quantity: '1',
            unit_price: variant.harga_modal ?? 0,
            images: variant.images ?? [],
        });
    }

    async function trySyncToBackend(item: RestockCartItem) {
        if (!toValue(options.isCreateMode)) return;
        if (!item.unit_price || item.unit_price <= 0) return;
        if (!item.quantity || Number(item.quantity) <= 0) return;

        try {
            await syncDraftItem(item.product_variant_id, item.quantity, item.unit_price);
        } catch (error) {
            console.error(error);
        }
    }

    async function removeItem(index: number) {
        const item = cart.value[index];

        if (toValue(options.isCreateMode) && item.unit_price > 0) {
            try {
                await apiFetch(draft_items.destroy.url(item.product_variant_id), {
                    method: 'DELETE',
                });
            } catch (error) {
                // Item might not exist in DB yet, ignore
            }
        }

        cart.value.splice(index, 1);
    }

    async function decreaseQty(variantId: number) {
        const item = cart.value.find((i) => i.product_variant_id === variantId);

        if (!item) {
            return;
        }

        const nextQty = (Number(item.quantity) || 0) - 1;

        if (nextQty <= 0) {
            const index = cart.value.findIndex((i) => i.product_variant_id === variantId);

            if (index !== -1) {
                await removeItem(index);
            }

            return;
        }

        item.quantity = String(nextQty);
        await trySyncToBackend(item);
    }

    async function updateQuantity(variantId: number, quantity: string) {
        const item = cart.value.find((i) => i.product_variant_id === variantId);

        if (!item) {
            return;
        }

        item.quantity = quantity;
        await trySyncToBackend(item);
    }

    async function updateUnitPrice(variantId: number, unitPrice: number) {
        const item = cart.value.find((i) => i.product_variant_id === variantId);

        if (!item) {
            return;
        }

        item.unit_price = unitPrice;
        await trySyncToBackend(item);
    }

    return {
        productSearch,
        cart,
        filteredProducts,
        subtotal,
        setCart,
        loadDraftItems,
        addProduct,
        removeItem,
        decreaseQty,
        updateQuantity,
        updateUnitPrice,
        getCartItem,
    };
}
