import { NotificationPlacements } from "../interface.js";
import { unit } from "@antdv-next/cssinjs";

//#region src/notification/style/placement.ts
const notificationMarginEdgeVar = "--notification-margin-edge";
/** Resolve the opposite block and inline edges for a placement. */
function getPlacementOffset(vertical, horizontal) {
	return {
		blockEnd: vertical === "top" ? "bottom" : "top",
		inlineEnd: horizontal === "left" ? "right" : "left"
	};
}
/** Convert placement offsets into the transform used by notice motion. */
function getMotionTransform(motionOffset) {
	return `translate3d(${motionOffset?.x ?? "0"}, ${motionOffset?.y ?? "0"}, 0) scale(var(--notification-scale, 1))`;
}
/** Build the placement metadata used by position and motion styles. */
function getPlacementStyleConfig(placement, motionOffset) {
	const vertical = placement.startsWith("bottom") ? "bottom" : "top";
	const horizontal = placement.endsWith("Right") ? "right" : "left";
	const { blockEnd, inlineEnd } = getPlacementOffset(vertical, horizontal);
	const isCenterPlacement = placement === "top" || placement === "bottom";
	const offset = placement === "top" || placement.endsWith("Left") ? `-${motionOffset}` : motionOffset;
	return {
		placement,
		vertical,
		blockEnd,
		horizontal,
		inlineEnd,
		motionOffset: isCenterPlacement ? {
			x: "-50%",
			y: offset
		} : { x: offset },
		baseMotionOffset: isCenterPlacement ? { x: "-50%" } : void 0,
		isCenterPlacement
	};
}
/** Get the list direction for a vertical placement. */
function getPlacementFlexDirection(vertical) {
	return vertical === "bottom" ? "column-reverse" : "column";
}
/** Keep configured top/bottom as the visible notice edge while list padding preserves shadows. */
function getPlacementInset(vertical) {
	const marginEdge = `var(${notificationMarginEdgeVar}, 0px)`;
	return `calc(var(--notification-${vertical}, ${marginEdge}) - ${marginEdge})`;
}
/** Get the transform origin used by stacked notice scaling. */
function getPlacementTransformOrigin(vertical) {
	return vertical === "bottom" ? "center top" : "center bottom";
}
/** Calculate the clip offset that preserves stack shadows. */
function getStackShadowClipOffset(token) {
	return unit(token.calc(token.marginXXL).mul(-1).equal());
}
/** Build the default stack clip-path for a visible notice. */
function getStackNoticeClipPath(token) {
	const offset = getStackShadowClipOffset(token);
	return `inset(${offset} ${offset} ${offset} ${offset})`;
}
/** Build the collapsed stack clip-path for a placement. */
function getPlacementStackClipPath(token, vertical) {
	const offset = getStackShadowClipOffset(token);
	return vertical === "bottom" ? `inset(${offset} ${offset} 50% ${offset})` : `inset(50% ${offset} ${offset} ${offset})`;
}
/** Generate styles for a single notification placement. */
function genPlacementStyle(token, config) {
	const { componentCls } = token;
	const { placement, vertical, blockEnd, horizontal, inlineEnd, isCenterPlacement } = config;
	const noticeCls = `${componentCls}-notice`;
	const noticeMotionCls = `${noticeCls}${componentCls}-fade`;
	const enterTransform = getMotionTransform(config.motionOffset);
	const baseTransform = getMotionTransform(config.baseMotionOffset);
	const transformOrigin = getPlacementTransformOrigin(vertical);
	return { [`&${componentCls}-${placement}`]: {
		[vertical]: getPlacementInset(vertical),
		[blockEnd]: "auto",
		display: "flex",
		flexDirection: getPlacementFlexDirection(vertical),
		...isCenterPlacement ? {
			marginInline: 0,
			left: "50%",
			right: "auto",
			transform: "translateX(-50%)"
		} : {
			[horizontal]: 0,
			[inlineEnd]: "auto"
		},
		[noticeCls]: {
			[vertical]: "var(--notification-y, 0)",
			...isCenterPlacement ? {
				left: "50%",
				transform: baseTransform
			} : { [horizontal]: "var(--notification-x, 0)" },
			transformOrigin
		},
		[`${noticeMotionCls}-appear-prepare, ${noticeMotionCls}-enter-prepare`]: {
			opacity: 0,
			transform: enterTransform,
			transition: "none"
		},
		[`${noticeMotionCls}-appear-start, ${noticeMotionCls}-enter-start`]: {
			opacity: 0,
			transform: enterTransform
		},
		[`${noticeMotionCls}-appear-active, ${noticeMotionCls}-enter-active`]: {
			opacity: 1,
			transform: baseTransform
		},
		[`${noticeMotionCls}-leave-start`]: {
			opacity: 1,
			transform: baseTransform
		},
		[`${noticeMotionCls}-leave-active`]: {
			opacity: 0,
			transform: enterTransform
		},
		[`&${componentCls}-stack:not(${componentCls}-stack-expanded)`]: {
			[noticeCls]: { clipPath: getPlacementStackClipPath(token, vertical) },
			[`${noticeCls}[data-notification-index='0']`]: { clipPath: getStackNoticeClipPath(token) }
		}
	} };
}
/** Generate placement styles for all enabled notification placements. */
function genNotificationPlacementRootStyle(token, placements = NotificationPlacements) {
	const { notificationMotionOffset } = token;
	const motionOffset = unit(notificationMotionOffset);
	return { ...placements.reduce((styles, placement) => ({
		...styles,
		...genPlacementStyle(token, getPlacementStyleConfig(placement, motionOffset))
	}), {}) };
}
/** Wrap placement styles under the component root selector. */
const genNotificationPlacementStyle = (token) => {
	const { componentCls } = token;
	return { [componentCls]: genNotificationPlacementRootStyle(token) };
};
var placement_default = genNotificationPlacementStyle;

//#endregion
export { placement_default as default };