import CrossIcon from "@Assets/Icons/cross.svg";
import Image from "next/image";
import React from "react";

import Typography, { ITypo } from "../Typography";
import classes from "./classes.module.scss";
import Footer from "./Elements/Footer";
import Header from "./Elements/Header";
import Loader from "./Elements/Loader";

export type IProps = {
	closeBtn?: boolean;
	header?: string | JSX.Element;
	footer?: JSX.Element | null;
	textLoader?: string | JSX.Element;
	isOpen: boolean;
	onClose: () => void;
	hasTransparentBackground?: boolean;
	hasContainerClosable?: boolean;
	withSideBackground?: boolean;
	children?: React.ReactNode;
	animationDelay?: number;
};

type IState = {
	willClose: boolean;
	isOpen: boolean;
};

export default class Modal extends React.Component<IProps, IState> {
	static defaultProps = {
		animationDelay: 250,
	};
	public rootRefElement = React.createRef<HTMLDivElement>();
	constructor(props: IProps) {
		super(props);
		this.close = this.close.bind(this);

		this.state = {
			willClose: false,
			isOpen: this.props.isOpen,
		};
	}

	public override render(): JSX.Element | null {
		if (!this.state.isOpen) return null;
		return (
			<div
				ref={this.rootRefElement}
				className={classes["root"]}
				data-side-background={this.props.withSideBackground}
				data-will-close={this.state.willClose.toString()}>
				<div className={classes["background"]} onClick={this.close} />
				<div className={[classes["container"], this.props.hasTransparentBackground && classes["transparant-background"]].join(" ")}>
					{this.props.closeBtn && (
						<div className={classes["cross"]}>
							<Image alt="Unplugged" src={CrossIcon} className={classes["close-icon"]} onClick={this.close} />
						</div>
					)}
					<div className={classes["sub-container"]}>
						{this.props.header && <Header content={this.props.header} />}

						<Typography typo={ITypo.TEXT_MD_REGULAR}>
							<>{this.props.children ? this.props.children : <Loader text={this.props.textLoader} />}</>
						</Typography>
						{this.props.children && this.props.footer && <Footer content={this.props.footer} />}
					</div>
				</div>
			</div>
		);
	}

	public override componentDidUpdate(prevProps: IProps): void {
		if (prevProps.isOpen !== this.props.isOpen && !this.props.isOpen) {
			this.setState({ willClose: true });
			window.setTimeout(() => {
				this.setState({
					isOpen: false,
					willClose: false,
				});
			}, this.props.animationDelay);
			document.body.style.overflow = "auto";
		}
		if (prevProps.isOpen !== this.props.isOpen && this.props.isOpen) {
			this.setState({ isOpen: true });
			document.body.style.overflow = "hidden";
		}
		this.rootRefElement.current?.style.setProperty("--animation-delay", this.props.animationDelay!.toString().concat("ms"));
	}

	public override componentDidMount(): void {
		document.addEventListener("keydown", this.handleKeyDown);
	}

	public override componentWillUnmount(): void {
		document.body.style.overflow = "auto";
		document.removeEventListener("keydown", this.handleKeyDown);
	}

	protected close() {
		if (this.props.hasContainerClosable === false) return;
		if (this.state.willClose) return;
		this.props.onClose();
	}

	private handleKeyDown = (e: KeyboardEvent): void => {
		if (e.key === "Escape" || e.key === "Esc") {
			this.props.onClose();
		}
	};
}
