import React, { ReactNode, useContext, useEffect, useState } from 'react';
import A11yDialog from 'react-a11y-dialog';

import { ledetekst } from '../diverse/Ledetekst.js';
import { Spinner } from './Spinner';
import { classnames } from '../';

const DialogContext = React.createContext({
	appRoot: '',
	dialogRoot: '',
});

function Dialog(props: {
	avbruddstekst?: string;
	children?: ReactNode;
	ekstraknapper?: ReactNode;
	handlingstekst?: string;
	spinnertekst?: string;
	harFeil?: boolean;
	open?: boolean;
	skjulAvbruddsknapp?: boolean;
	skjulHandlingsknapp?: boolean;
	tittel: string;
	vedHandling?: () => any;
	vedLukking?: () => any;
	disableKnapper?: boolean;
	bredDialog?: boolean;
}) {
	const [dialog, setDialog] = useState<null | A11yDialog>(null);
	const [laster, setLaster] = useState(false);
	const { appRoot, dialogRoot } = useContext(DialogContext);

	useEffect(() => {
		if (props.open && dialog) {
			dialog.show();
		}
	}, [props.open, dialog]);

	useEffect(() => {
		if (!dialog) return;
		const mottaLukking = () => {
			if (props.vedLukking) {
				props.vedLukking();
			}
		};
		dialog.on('hide', mottaLukking);

		return () => {
			try {
				dialog.off('hide', mottaLukking);
			} catch (e) {
				// dialog.off() vil feile hver eneste gang når vi navigerer bort fra modal.
				// Forbedring: Hvordan vite at vi ikke skal kalle dialog.off() ?
			}
		};
	}, [dialog, props.vedLukking]);

	const mottaHandling = () => {
		if (typeof props.vedHandling !== 'function' || laster) {
			return;
		}
		setLaster(true);
		Promise.resolve(props.vedHandling())
			// Legger på en liten delay for å sette laster til false, for å unngå flicker hvis
			// handlingen lukker dialogen
			.then(() => setTimeout(() => setLaster(false), 250));
	};
	if (!props.open) return null;

	const avbruddstekst =
		props.avbruddstekst ||
		ledetekst.getTekst('arbeidsvarsling.frontendkomponenter.Dialog.avbryt');
	const handlingstekst =
		props.handlingstekst ||
		ledetekst.getTekst(
			'arbeidsvarsling.frontendkomponenter.Dialog.' +
				(props.harFeil ? 'tilbake' : 'handling')
		);
	const spinnertekst =
		props.spinnertekst ||
		ledetekst.getTekst('arbeidsvarsling.frontendkomponenter.Dialog.laster');

	const skalViseKnapperad = !(
		props.skjulAvbruddsknapp === true &&
		props.skjulHandlingsknapp === true &&
		props.ekstraknapper == null
	);

	return (
		<A11yDialog
			id="apv-arbeidsvarsling-dialog"
			appRoot={appRoot}
			dialogRoot={dialogRoot}
			dialogRef={(dialog) => setDialog(dialog)}
			title={props.tittel}
			closeButtonContent="×"
			useDialog={false}
			classNames={{
				base: 'dialog-wrapper',
				overlay: 'dialog-backdrop',
				element: classnames('dialog-modalboks', {
					'bred-dialog': props.bredDialog,
				}),
				closeButton: 'dialog-lukk',
				title: classnames('kapitteltittel util-tekst-sentrert', {
					'advarsel-om-feil': props.harFeil,
				}),
			}}
		>
			<div className="dialog-innhold util-tekst-sentrert">
				{props.children}
				{laster ? (
					<Spinner aktivert={laster} tekst={spinnertekst} />
				) : skalViseKnapperad ? (
					<div className="knapperad knapperad-mobil">
						{!props.skjulAvbruddsknapp && (
							<button
								type="button"
								id="avbryt"
								className="knapp"
								disabled={props.disableKnapper}
								onClick={() => dialog?.hide()}
							>
								{avbruddstekst}
							</button>
						)}
						{props.ekstraknapper}
						{!props.skjulHandlingsknapp && (
							<button
								type="button"
								className="knapp knapp-handling knapp-neste"
								disabled={props.disableKnapper}
								onClick={mottaHandling}
							>
								{handlingstekst}
							</button>
						)}
					</div>
				) : null}
			</div>
		</A11yDialog>
	);
}

export { Dialog, DialogContext };
