import React, { createContext, FC, useContext, useState } from "react";
import { useDisclosure } from "@mantine/hooks";
import { CardsWithExcelForm, ProductExcelData } from "../drawers/PrefillCardWithExcelDrawer/types.tsx";
import { FileWithPath } from "@mantine/dropzone";
import { notifications } from "../../../shared/lib/notifications.ts";
import { CardService, type ProductFromExcelSchema, ProductSchema, StatusSchema } from "../../../client";
import UseExcelDropzone from "../../../types/UseExcelDropzone.tsx";
import { useForm, UseFormReturnType } from "@mantine/form";
import { useCardPageContext } from "./CardPageContext.tsx";

type PrefillCardsWithExcelContextState = {
    prefillWithExcelOpened: boolean;
    prefillWithExcelOnClose: () => void;
    prefillWithExcelOnOpen: () => void;
    barcodeProductsMap: Map<string, ProductExcelData>,
    onProductSelectChange: (barcode: string, selectedProduct: ProductSchema) => void,
    onDrop: (files: FileWithPath[]) => void;
    excelDropzone: UseExcelDropzone;
    createCards: (values: CardsWithExcelForm, status: StatusSchema) => void;
    form: UseFormReturnType<CardsWithExcelForm>;
    errors: string[];
};

const PrefillCardsWithExcelContext = createContext<PrefillCardsWithExcelContextState | undefined>(
    undefined,
);

const usePrefillCardsWithExcelContextState = () => {
    const [prefillWithExcelOpened, { open, close }] = useDisclosure(false);
    const { refetchCards } = useCardPageContext();
    const [isLoading, setIsLoading] = useState(false);
    const [errors, setErrors] = useState<string[]>([]);
    const excelDropzone: UseExcelDropzone = {
        isLoading,
        setIsLoading,
    };

    const form = useForm<CardsWithExcelForm>({
        validate: {
            client: client => !client && "Выберите клиента",
        },
    });

    const [barcodeProductsMap, setBarcodeProductsMap] = useState<Map<string, ProductExcelData>>(new Map());

    const onDrop = (files: FileWithPath[]) => {
        if (files.length > 1) {
            notifications.error({ message: "Прикрепите одно изображение" });
            return;
        }
        const file = files[0];

        setIsLoading(true);
        CardService.parseDealsExcel({
            formData: {
                upload_file: file,
            },
        })
            .then(res => {
                const barcodeProductsMap = new Map();
                res.rows.forEach((row) => {
                    const productsData: ProductExcelData = row;
                    productsData.selectedProduct = productsData.products[0];
                    barcodeProductsMap.set(row.barcode, row);
                });
                setBarcodeProductsMap(barcodeProductsMap);
                setErrors(res.errors);
            })
            .catch(error => {
                notifications.error({ message: error.toString() });
            })
            .finally(() => setIsLoading(false));
    };

    const onProductSelectChange = (barcode: string, selectedProduct: ProductSchema) => {
        const newBarcodeProductsMap = new Map(barcodeProductsMap);
        const productsData = newBarcodeProductsMap.get(barcode);
        if (!productsData) return;
        productsData.selectedProduct = selectedProduct;

        newBarcodeProductsMap.set(
            barcode,
            productsData,
        );
        setBarcodeProductsMap(newBarcodeProductsMap);
    };

    const prefillWithExcelOnClose = () => {
        close();
        setBarcodeProductsMap(new Map());
        form.reset();
    };

    const createCards = (values: CardsWithExcelForm, status: StatusSchema) => {
        const products: ProductFromExcelSchema[] = barcodeProductsMap.entries().map(([, productData]) => {
            return {
                productId: productData.selectedProduct!.id,
                citiesBreakdown: productData.breakdowns,
            };
        }).toArray();

        CardService.createDealsExcel({
            requestBody: {
                products,
                clientId: values.client?.id ?? -1,
                statusId: status.id,
            },
        })
            .then(({ ok, message }) => {
                notifications.guess(ok, { message });
                if (ok) prefillWithExcelOnClose();
                refetchCards();
            })
            .catch(err => console.log(err));
    };

    return {
        prefillWithExcelOpened,
        prefillWithExcelOnClose,
        prefillWithExcelOnOpen: open,
        barcodeProductsMap,
        onProductSelectChange,
        onDrop,
        excelDropzone,
        createCards,
        form,
        errors,
    };
};

type PrefillCardsWithExcelContextProviderProps = {
    children: React.ReactNode;
};

export const PrefillCardsWithExcelContextProvider: FC<PrefillCardsWithExcelContextProviderProps> = ({ children }) => {
    const state = usePrefillCardsWithExcelContextState();
    return (
        <PrefillCardsWithExcelContext.Provider value={state}>
            {children}
        </PrefillCardsWithExcelContext.Provider>
    );
};

export const usePrefillCardsWithExcelContext = () => {
    const context = useContext(PrefillCardsWithExcelContext);
    if (!context) {
        throw new Error(
            "usePrefillCardsWithExcelContext must be used within a PrefillCardsWithExcelContextProvider",
        );
    }
    return context;
};
