import { Dropzone, DropzoneProps, FileWithPath } from "@mantine/dropzone";
import { FC, useEffect, useState } from "react";
import { Button, Fieldset, Flex, Group, Loader, rem, Text } from "@mantine/core";
import { IconPhoto, IconUpload, IconX } from "@tabler/icons-react";
import { omit } from "lodash";
import { notifications } from "../../shared/lib/notifications.ts";
import { ProductService } from "../../client";

// Barcode image aspects ratio should be equal 58/40
const BARCODE_IMAGE_RATIO = 1.45;

interface RestProps {
    productId?: number;
}

type Props = Omit<DropzoneProps, "onDrop"> & RestProps;

const BarcodeImageDropzone: FC<Props> = (props: Props) => {
    const [isLoading, setIsLoading] = useState(false);
    const restProps = omit(props, [
        "productId",
    ]);
    const [barcodeImageUrl, setBarcodeImageUrl] = useState<string>();

    useEffect(() => {
        getBarcodeImage();
    }, []);

    const getBarcodeImage = () => {
        if (!props.productId) return;

        ProductService.getProductBarcodeImage({
            productId: props.productId,
        })
            .then(res => {
                if (res.barcodeImageUrl) {
                    setBarcodeImageUrl(res.barcodeImageUrl);
                }
            });
    };

    const uploadImage = (productId: number, file: File) => {
        ProductService.uploadProductBarcodeImage({
            productId: productId,
            formData: {
                upload_file: file,
            },
        })
            .then(({ ok, message, barcodeImageUrl }) => {
                notifications.guess(ok, { message });

                if (ok && barcodeImageUrl) {
                    setBarcodeImageUrl(barcodeImageUrl);
                }
            })
            .catch(error => {
                notifications.error({ message: error.toString() });
            })
            .finally(() => {
                setIsLoading(false);
            })
    };

    const onDrop = (files: FileWithPath[]) => {
        if (!props.productId) return;
        if (files.length > 1) {
            notifications.error({ message: "Прикрепите один pdf файл" });
            return;
        }
        const file = files[0];
        setIsLoading(true);
        uploadImage(props.productId, file);
    };

    const deleteImage = () => {
        if (!props.productId) return;
        ProductService.deleteProductBarcodeImage({ productId: props.productId })
            .then(({ ok, message }) => {
                notifications.guess(ok, { message });

                if (!ok) return;
                setBarcodeImageUrl("");
            })
            .catch(error => {
                notifications.error({ message: error.toString() });
            });
    };

    const getBody = () => {
        return barcodeImageUrl ? (
            <object style={{
                aspectRatio: BARCODE_IMAGE_RATIO,
                width: "240px",
            }} data={barcodeImageUrl} />
        ) : (
            <Dropzone
                {...restProps}
                accept={[
                    "application/pdf",
                ]}
                multiple={false}
                onDrop={onDrop}>
                <Group
                    justify="center"
                    gap="xl"
                    style={{ pointerEvents: "none" }}>
                    <Dropzone.Accept>
                        <IconUpload
                            style={{
                                width: rem(52),
                                height: rem(52),
                                color: "var(--mantine-color-blue-6)",
                            }}
                            stroke={1.5}
                        />
                    </Dropzone.Accept>
                    <Dropzone.Reject>
                        <IconX
                            style={{
                                width: rem(52),
                                height: rem(52),
                                color: "var(--mantine-color-red-6)",
                            }}
                            stroke={1.5}
                        />
                    </Dropzone.Reject>
                    <Dropzone.Idle>
                        <IconPhoto
                            style={{
                                width: rem(52),
                                height: rem(52),
                                color: "var(--mantine-color-dimmed)",
                            }}
                            stroke={1.5}
                        />
                    </Dropzone.Idle>

                    <div style={{ textAlign: "center" }}>
                        <Text
                            size="xl"
                            inline>
                            Перенесите или нажмите чтоб выбрать файл <br/>
                            Pdf-файл должен содержать 1 страницу размером 58 х 40
                        </Text>
                    </div>
                </Group>
            </Dropzone>
        );
    };

    return (
        <Flex
            gap={rem(10)}
            direction={"column"}>
            <Fieldset legend={"Штрихкод"}>
                <Flex justify={"center"}>
                    {isLoading ? <Loader /> : getBody()}
                </Flex>
            </Fieldset>
            {barcodeImageUrl && (
                <>
                    <Button
                        onClick={() => setBarcodeImageUrl("")}
                        variant={"default"}>
                        Заменить штрихкод
                    </Button>
                    <Button
                        onClick={() => deleteImage()}
                        variant={"default"}>
                        Удалить штрихкод
                    </Button>
                </>
            )}
        </Flex>
    );
};

export default BarcodeImageDropzone;
