import { useForm } from "@mantine/form";
import { ContextModalProps } from "@mantine/modals";
import { Button, Flex, NumberInput, rem, Text } from "@mantine/core";
import getRestProducts from "../utils/getRestProducts.tsx";
import {
    CreateBoxInCardSchema,
    CreateBoxInPalletSchema,
    CreateShippingProductSchema,
    CardProductSchema,
    CardSchema,
    ProductSchema,
    ShippingService,
    UpdateBoxSchema,
    UpdateShippingProductSchema,
} from "../../../../../client";
import { notifications } from "../../../../../shared/lib/notifications.ts";
import { ShippingData, ShippingModalForm } from "../types/ShippingProductData.tsx";
import { useEffect, useState } from "react";
import ShippingProductSelect from "../components/ShippingProductSelect.tsx";


type Props = {
    updateOnSubmit: () => void;
    card: CardSchema;
    isBox: boolean;
    shippingData: Partial<ShippingData>;
}

const ShippingProductModal = ({
                                  context,
                                  id,
                                  innerProps,
                              }: ContextModalProps<Props>) => {
    const [restProducts, setRestProducts] = useState<Map<number, CardProductSchema>>(new Map());
    const [restProductsSelectData, setRestProductSelectData] = useState<ProductSchema[]>([]);

    const getRestProductQuantity = () => {
        if (form.values.product) {
            const restProduct = restProducts.get(form.values.product.id);
            if (restProduct) {
                return restProduct.quantity;
            }
        }
        return 10000;
    };

    const findProductById = (productId?: number | null) => {
        const cardProduct = innerProps.card.products.find(p => p.product.id === productId);
        return cardProduct ? cardProduct.product : null;
    };

    const initialValues: ShippingModalForm = {
        quantity: innerProps.shippingData.quantity ?? 0,
        product: findProductById(innerProps.shippingData.productId),
    };
    const form = useForm<ShippingModalForm>({
        initialValues,
        validate: {
            product: product => !product && "Необходимо выбрать товар",
            quantity: quantity => quantity > getRestProductQuantity() ? "Слишком много товара" :
                quantity === 0 && "Слишком мало товара",
        },
    });

    useEffect(() => {
        const data = getRestProducts({
            card: innerProps.card,
            unaccountedValues: innerProps.shippingData as UpdateShippingProductSchema | UpdateBoxSchema,
        });
        setRestProducts(data.restProducts);
        setRestProductSelectData(data.restProductsSelectData);
    }, [innerProps.card]);

    const updateBox = () => {
        const data = {
            ...innerProps.shippingData,
            ...form.values,
            productId: form.values.product?.id,
        } as CreateBoxInPalletSchema | CreateBoxInCardSchema | UpdateBoxSchema;

        ShippingService.updateBox({
            requestBody: { data },
        })
            .then(({ ok, message }) => {
                notifications.guess(ok, { message: message });
                innerProps.updateOnSubmit();
                if (ok) context.closeContextModal(id);
            })
            .catch(err => console.log(err));
    };

    const updateShippingProduct = () => {
        const data = {
            ...innerProps.shippingData,
            ...form.values,
            productId: form.values.product?.id,
        } as CreateShippingProductSchema | UpdateShippingProductSchema;

        ShippingService.updateShippingProduct({
            requestBody: { data },
        })
            .then(({ ok, message }) => {
                notifications.guess(ok, { message: message });
                innerProps.updateOnSubmit();
                if (ok) context.closeContextModal(id);
            })
            .catch(err => console.log(err));
    };

    const onSubmit = () => {
        if (innerProps.isBox) {
            updateBox();
        } else {
            updateShippingProduct();
        }
    };

    const getRestQuantityText = () => {
        if (!form.values.product) return;

        const restQuantityInDeal = getRestProductQuantity();
        const restQuantity = restQuantityInDeal - form.values.quantity;

        if (restQuantity >= 0) {
            return <Text>Осталось распределить {restQuantity} шт.</Text>;
        }
        return <Text>Введено слишком большое количество.<br />Доступно {restQuantityInDeal} шт.</Text>;
    };

    return (
        <form onSubmit={form.onSubmit(() => onSubmit())}>
            <Flex
                direction={"column"}
                gap={rem(10)}
            >
                <ShippingProductSelect
                    {...form.getInputProps("product")}
                    data={restProductsSelectData}
                />

                {getRestQuantityText()}

                <NumberInput
                    label={"Количество"}
                    hideControls
                    {...form.getInputProps("quantity")}
                    min={0}
                />

                <Button
                    variant={"default"}
                    type={"submit"}
                >
                    Сохранить
                </Button>
            </Flex>
        </form>
    );
};

export default ShippingProductModal;
