import React, { useState, useRef, useEffect, FC } from "react";
import ReactCrop, { Crop, PixelCrop } from "react-image-crop";
import {
    Box,
    Button,
    Modal,
    Slider,
    Typography,
    useMediaQuery,
    useTheme,
} from "@mui/material";

import { canvasPreview } from "./utils/canvasPreview";
import { useDebounceEffect } from "./utils/useDebounceEffect";

import { ResetIcon } from "@icons/ResetIcon";

import "react-image-crop/dist/ReactCrop.css";
import { CropIcon } from "@icons/CropIcon";

interface Iprops {
    opened: boolean;
    onClose: React.Dispatch<React.SetStateAction<boolean>>;
    picture?: string;
    onCropPress?: (imageUrl: string) => void;
}

export const CropModal: FC<Iprops> = ({ opened, onClose, picture, onCropPress }) => {
    const [imgSrc, setImgSrc] = useState("");

    const imgRef = useRef<HTMLImageElement>(null);
    const fileInputRef = useRef<HTMLInputElement>(null);
    const previewCanvasRef = useRef<HTMLCanvasElement>(null);
    const hiddenAnchorRef = useRef<HTMLAnchorElement>(null);
    const blobUrlRef = useRef("");
    const [crop, setCrop] = useState<Crop>();
    const [completedCrop, setCompletedCrop] = useState<PixelCrop>();
    const [rotate, setRotate] = useState(0);
    const [darken, setDarken] = useState(0);

    const theme = useTheme();
    const isMobile = useMediaQuery(theme.breakpoints.down(786));

    useEffect(() => {
        if (picture) {
            setImgSrc(picture);
        }
    }, [picture]);

    const styleModal = {
        position: "absolute",
        top: "50%",
        left: "50%",
        transform: "translate(-50%, -50%)",
        width: isMobile ? "343px" : "620px",
        bgcolor: "background.paper",
        boxShadow: 24,
        padding: "20px",
        borderRadius: "8px",
    };

    const styleSlider = {
        width: isMobile ? "350px" : "250px",
        color: "#7E2AEA",
        height: "12px",
        "& .MuiSlider-track": {
            border: "none",
        },
        "& .MuiSlider-rail": {
            backgroundColor: "#F2F3F7",
            border: `1px solid #9A9AAF`,
        },
        "& .MuiSlider-thumb": {
            height: 26,
            width: 26,
            border: `6px solid #7E2AEA`,
            backgroundColor: "white",
            boxShadow: `0px 0px 0px 3px white,
                    0px 4px 4px 3px #C3C8DD`,
            "&:focus, &:hover, &.Mui-active, &.Mui-focusVisible": {
                boxShadow: `0px 0px 0px 3px white,
                        0px 4px 4px 3px #C3C8DD`,
            },
        },
    };

    const rotateImage = () => {
        const newRotation = (rotate + 90) % 360;
        setRotate(newRotation);
    };

    const onSelectFile = (event: React.ChangeEvent<HTMLInputElement>) => {
        if (event.target.files && event.target.files.length > 0) {
            setCrop(undefined);
            const reader = new FileReader();
            reader.addEventListener("load", () =>
                setImgSrc(reader.result?.toString() || "")
            );
            reader.readAsDataURL(event.target.files[0]);
        }
    };

    const onDownloadCropClick = () => {
        if (!previewCanvasRef.current) {
            throw new Error("Crop canvas does not exist");
        }

        const canvasCopy = document.createElement("canvas");
        const ctx = canvasCopy.getContext("2d");
        canvasCopy.width = previewCanvasRef.current.width;
        canvasCopy.height = previewCanvasRef.current.height;
        ctx!.filter = `brightness(${100 - darken}%)`;
        ctx!.drawImage(previewCanvasRef.current, 0, 0);

        canvasCopy.toBlob((blob) => {
            if (!blob) {
                throw new Error("Failed to create blob");
            }
            if (blobUrlRef.current) {
                URL.revokeObjectURL(blobUrlRef.current);
            }
            blobUrlRef.current = URL.createObjectURL(blob);
            hiddenAnchorRef.current!.href = blobUrlRef.current;
            hiddenAnchorRef.current!.click();

            setImgSrc(blobUrlRef.current);
            onCropPress?.(blobUrlRef.current);
        });
    };

    useDebounceEffect(
        async () => {
            if (
                completedCrop?.width &&
                completedCrop?.height &&
                imgRef.current &&
                previewCanvasRef.current
            ) {
                canvasPreview(
                    imgRef.current,
                    previewCanvasRef.current,
                    completedCrop,
                    rotate
                );
            }
        },
        100,
        [completedCrop, rotate]
    );

    const [width, setWidth] = useState<number>(0);

    const getImageSize = () => {
        if (imgRef.current) {
            const imageWidth = imgRef.current.naturalWidth;
            const imageHeight = imgRef.current.naturalHeight;

            const aspect = imageWidth / imageHeight;


            if (aspect <= 1.333) {
                setWidth(240);
            }
            if (aspect >= 1.5) {
                setWidth(580);
            }
            if (aspect >= 1.778) {
                setWidth(580);
            }
        }
    };

    return (
        <>
            <Modal
                open={opened}
                onClose={onClose}
                aria-labelledby="modal-modal-title"
                aria-describedby="modal-modal-description"
            >
                <Box sx={styleModal}>
                    <Box
                        sx={{
                            height: "320px",
                            padding: "10px",
                            backgroundSize: "cover",
                            backgroundRepeat: "no-repeat",

                            display: "flex",
                            alignItems: "center",
                            justifyContent: "center",
                        }}
                    >
                        {imgSrc && (
                            <ReactCrop
                                crop={crop}
                                onChange={(_, percentCrop) => setCrop(percentCrop)}
                                onComplete={(c) => setCompletedCrop(c)}
                                maxWidth={500}
                                minWidth={50}
                                maxHeight={320}
                                minHeight={50}
                            >
                                <img
                                    onLoad={getImageSize}
                                    ref={imgRef}
                                    alt="Crop me"
                                    src={imgSrc}
                                    style={{
                                        filter: `brightness(${100 - darken}%)`,
                                        transform: ` rotate(${rotate}deg)`,
                                        maxWidth: "580px",
                                        maxHeight: "320px",
                                    }}
                                    width={width}
                                />
                            </ReactCrop>
                        )}
                    </Box>
                    <Box
                        sx={{
                            color: "#7E2AEA",
                            display: "flex",
                            alignItems: "center",
                            justifyContent: "center",
                            fontSize: "16xp",
                            fontWeight: "600",
                            marginBottom: "50px",
                        }}
                    >
                        <Typography sx={{ color: "#7E2AEA", lineHeight: "0px" }}>
                            {crop?.width ? Math.round(crop.width) + "px" : ""}
                        </Typography>
                        <Typography sx={{ color: "#7E2AEA", lineHeight: "0px" }}>
                            {crop?.height ? Math.round(crop.height) + "px" : ""}
                        </Typography>
                    </Box>

                    <Box
                        sx={{
                            display: isMobile ? "block" : "flex",
                            alignItems: "end",
                            justifyContent: "space-between",
                        }}
                    >
                        <ResetIcon
                            onClick={rotateImage}
                            style={{ marginBottom: "10px", cursor: "pointer" }}
                        />
                        <Box>
                            <Typography sx={{ color: "#9A9AAF", fontSize: "16px" }}>
                                Размер
                            </Typography>
                            <Slider
                                sx={styleSlider}
                                value={width}
                                min={50}
                                max={580}
                                step={1}
                                onChange={(_, newValue) => {
                                    setWidth(newValue as number);
                                }}
                            />
                        </Box>
                        <Box>
                            <Typography sx={{ color: "#9A9AAF", fontSize: "16px" }}>
                                Затемнение
                            </Typography>
                            <Slider
                                sx={styleSlider}
                                value={darken}
                                min={0}
                                max={100}
                                step={1}
                                onChange={(_, newValue) => setDarken(newValue as number)}
                            />
                        </Box>
                    </Box>
                    <Box
                        sx={{
                            marginTop: "40px",
                            width: "100%",
                            display: "flex",
                            justifyContent: "end",
                        }}
                    >
                        <input
                            style={{ display: "none", zIndex: "-999" }}
                            ref={fileInputRef}
                            type="file"
                            accept="image/*"
                            onChange={onSelectFile}
                        />
                        <Button
                            onClick={() => fileInputRef.current?.click()}
                            disableRipple
                            sx={{
                                width: "215px",
                                height: "48px",
                                color: "#7E2AEA",
                                borderRadius: "8px",
                                border: "1px solid #7E2AEA",
                                marginRight: "10px",
                            }}
                        >
                            Загрузить оригинал
                        </Button>
                        <Button
                            onClick={onDownloadCropClick}
                            disableRipple
                            variant="contained"
                            sx={{
                                padding: "10px 20px",
                                borderRadius: "8px",
                                background: theme.palette.brightPurple.main,
                                fontSize: "18px",
                            }}
                        >
                            <CropIcon />
                            Обрезать
                        </Button>
                    </Box>
                </Box>
            </Modal>
            {completedCrop && (
                <div>
                    <canvas
                        ref={previewCanvasRef}
                        style={{
                            display: "none",
                            zIndex: "-999",
                            border: "1px solid black",
                            objectFit: "contain",
                            width: completedCrop.width,
                            height: completedCrop.height,
                        }}
                    />
                </div>
            )}
            <div>
                <a
                    href="#hidden"
                    ref={hiddenAnchorRef}
                    download
                    style={{
                        display: "none",
                    }}
                >
                    Hidden download
                </a>
            </div>
        </>
    );
};
