/**
 * The destructive-action confirmation (milestone 23, ruling 5), which replaces
 * every `window.confirm` call in the app.
 *
 * `role="alertdialog"` rather than `dialog`: the message is the reason the
 * dialog exists, so it is announced with the dialog instead of after it. The
 * overlay is deliberately not dismissable — a delete needs an explicit answer,
 * and a stray outside click is not one. Escape still cancels.
 */

import type { ReactNode } from "react";
import * as stylex from "@stylexjs/stylex";
import { Dialog as AriaDialog, Heading, Modal, ModalOverlay } from "react-aria-components";
import { colors } from "./tokens.stylex";
import { styles as shared } from "./styles";

interface Props {
	isOpen: boolean;
	title: string;
	/** The full sentence the operator reads before confirming; names the entity. */
	message: string;
	confirmLabel: string;
	/**
	 * Stands in for the confirm action when the write can no longer land, the way
	 * an open edit dialog drops its Save. Closing the dialog instead would throw
	 * focus at a control that is now disabled and say nothing about why, so the
	 * question stays on screen and only the answer that would fail is withdrawn.
	 * Cancel is always live.
	 */
	lock?: ReactNode;
	onConfirm: () => void;
	onCancel: () => void;
}

const styles = stylex.create({
	overlay: {
		position: "fixed",
		inset: 0,
		zIndex: 50,
		display: "flex",
		alignItems: "center",
		justifyContent: "center",
		padding: "1rem",
		backgroundColor: "rgba(0, 0, 0, 0.4)",
	},
	panel: {
		width: "100%",
		maxWidth: "26rem",
		borderRadius: "0.5rem",
		borderWidth: 1,
		borderStyle: "solid",
		borderColor: colors.dangerBorder,
		backgroundColor: colors.surfaceRaised,
		color: colors.text,
		padding: "1.5rem",
		boxShadow: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)",
	},
	body: {
		outlineStyle: "none",
	},
	title: {
		fontSize: "1.125rem",
		lineHeight: "1.75rem",
		fontWeight: 600,
	},
	message: {
		marginTop: "0.5rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		color: colors.textMuted,
	},
	actions: {
		display: "flex",
		justifyContent: "flex-end",
		gap: "0.5rem",
		marginTop: "1.5rem",
	},
	dangerButton: {
		cursor: { default: "pointer", ":disabled": "not-allowed" },
		borderRadius: "0.25rem",
		borderStyle: "none",
		backgroundColor: colors.danger,
		color: colors.primaryText,
		paddingInline: "0.75rem",
		paddingBlock: "0.375rem",
		fontSize: "0.875rem",
		lineHeight: "1.25rem",
		fontWeight: 500,
	},
});

export default function ConfirmDialog({ isOpen, title, message, confirmLabel, lock, onConfirm, onCancel }: Props) {
	return (
		<ModalOverlay
			isOpen={isOpen}
			onOpenChange={(open) => {
				if (!open) onCancel();
			}}
			className={() => stylex.props(styles.overlay).className ?? ""}
		>
			<Modal className={() => stylex.props(styles.panel).className ?? ""}>
				<AriaDialog role="alertdialog" {...stylex.props(styles.body)}>
					<Heading slot="title" level={2} {...stylex.props(styles.title)}>
						{title}
					</Heading>
					<p {...stylex.props(styles.message)}>{message}</p>
					<div {...stylex.props(styles.actions)}>
						<button type="button" onClick={onCancel} {...stylex.props(shared.button, shared.focusRing)}>
							Cancel
						</button>
						{lock === undefined ? (
							<button
								type="button"
								onClick={onConfirm}
								{...stylex.props(styles.dangerButton, shared.focusRing)}
							>
								{confirmLabel}
							</button>
						) : (
							lock
						)}
					</div>
				</AriaDialog>
			</Modal>
		</ModalOverlay>
	);
}
