import Button from "@/components/lib/layout/Button";
import Stack from "@/components/lib/layout/Stack";
import { ImagePlus, X } from "lucide-react";
import React, { DetailedHTMLProps } from "react";
import Card from "@/components/lib/elements/Card";
import Span from "@/components/lib/layout/Span";
import Center from "@/components/lib/layout/Center";
import imageInputToBase64, {
    ImageInputToBase64FunctionReturn,
} from "../utils/form/imageInputToBase64";
import { twMerge } from "tailwind-merge";

type ImageUploadProps = {
    onChange?: (imgData: ImageInputToBase64FunctionReturn | undefined) => any;
    fileInputProps?: DetailedHTMLProps<
        React.InputHTMLAttributes<HTMLInputElement>,
        HTMLInputElement
    >;
    wrapperProps?: DetailedHTMLProps<
        React.HTMLAttributes<HTMLDivElement>,
        HTMLDivElement
    >;
    placeHolderWrapper?: DetailedHTMLProps<
        React.HTMLAttributes<HTMLDivElement>,
        HTMLDivElement
    >;
    previewImageWrapperProps?: DetailedHTMLProps<
        React.HTMLAttributes<HTMLDivElement>,
        HTMLDivElement
    >;
    previewImageProps?: DetailedHTMLProps<
        React.ImgHTMLAttributes<HTMLImageElement>,
        HTMLImageElement
    >;
};

export default function ImageUpload({
    onChange,
    fileInputProps,
    wrapperProps,
    placeHolderWrapper,
    previewImageWrapperProps,
    previewImageProps,
}: ImageUploadProps) {
    const [src, setSrc] = React.useState<string | undefined>(undefined);
    const inputRef = React.useRef<HTMLInputElement>();

    return (
        <Stack
            className={twMerge("w-full", wrapperProps?.className)}
            {...wrapperProps}
        >
            <input
                type="file"
                className={twMerge("hidden", fileInputProps?.className)}
                {...fileInputProps}
                onChange={(e) => {
                    imageInputToBase64({ imageInput: e.target }).then((res) => {
                        setSrc(res.imageBase64Full);
                        onChange?.(res);
                        fileInputProps?.onChange?.(e);
                    });
                }}
                ref={inputRef as any}
            />

            {src ? (
                <Card className="w-full relative" {...previewImageWrapperProps}>
                    <img
                        src={src}
                        className="w-full h-[300px] object-contain"
                        {...previewImageProps}
                    />
                    <Button
                        variant="ghost"
                        className="absolute p-2 top-2 right-2 z-20"
                        onClick={(e) => {
                            setSrc(undefined);
                            onChange?.(undefined);
                        }}
                    >
                        <X className="text-slate-950" />
                    </Button>
                </Card>
            ) : (
                <Card
                    className={twMerge(
                        "w-full h-[300px] cursor-pointer hover:bg-slate-100 dark:hover:bg-white/20",
                        placeHolderWrapper?.className
                    )}
                    onClick={(e) => {
                        inputRef.current?.click();
                        placeHolderWrapper?.onClick?.(e);
                    }}
                    {...placeHolderWrapper}
                >
                    <Center>
                        <Stack className="items-center gap-2">
                            <ImagePlus className="text-slate-400" />
                            <Span size="smaller" variant="faded">
                                Click to Upload Image
                            </Span>
                        </Stack>
                    </Center>
                </Card>
            )}
        </Stack>
    );
}
