import {
	buildDefaultAbsoluteAnchors,
	closingAssetFromCanvasTop,
	closingAssetToCanvasTop,
	computeLetterContentAreaPx,
	DEFAULT_LETTER_PAGE_MARGINS_PX,
	isClosingLayoutAnchor,
	migrateClosingAssetTopFromPageAbsolute,
	type LetterLanguage,
	type LetterPageMarginsPx,
} from "../utils/letter-page-dimensions";

export type LayoutPositionValue = {
	top?: number;
	left?: number;
	mode?: string;
	offsetX?: number;
	offsetY?: number;
};

export {
	buildDefaultAbsoluteAnchors,
	buildDefaultClosingAssetAnchors,
	closingAssetFromCanvasTop,
	closingAssetToCanvasTop,
	computeLetterContentAreaPx,
	DEFAULT_LETTER_PAGE_MARGINS_PX,
	PDF_PAGE_HEIGHT_PX,
	PDF_PAGE_WIDTH_PX,
	type LetterLanguage,
} from "../utils/letter-page-dimensions";

export type LayoutPositionAnchor =
	| "signatures"
	| "seal"
	| "stamp"
	| "senderSignature"
	| "senderStamp";

const DEFAULT_POSITION: LayoutPositionValue = {
	top: 0,
	left: 0,
};

function buildDefaultAnchors(
	margins: LetterPageMarginsPx = DEFAULT_LETTER_PAGE_MARGINS_PX,
	language: LetterLanguage = "am",
) {
	return buildDefaultAbsoluteAnchors(margins, language);
}

function parseCoord(value: unknown, fallback = 0): number {
	if (typeof value === "number" && Number.isFinite(value)) {
		return Math.round(value);
	}
	if (typeof value === "string" && value.trim() !== "") {
		const parsed = Number.parseFloat(value);
		if (Number.isFinite(parsed)) return Math.round(parsed);
	}
	return fallback;
}

export function normalizeLayoutPositionValue(
	value: unknown,
	anchor?: LayoutPositionAnchor,
	margins: LetterPageMarginsPx = DEFAULT_LETTER_PAGE_MARGINS_PX,
	language: LetterLanguage = "am",
): LayoutPositionValue {
	const anchors = buildDefaultAnchors(margins, language);
	const anchorPos = anchor ? anchors[anchor] : DEFAULT_POSITION;

	if (value == null || typeof value !== "object" || Array.isArray(value)) {
		return { ...anchorPos };
	}

	const record = value as Record<string, unknown>;
	const hadAbsoluteCoords =
		record.top != null ||
		record.left != null ||
		record.mode === "absolute";

	let top: number;
	let left: number;

	if (hadAbsoluteCoords) {
		top =
			parseCoord(record.top, anchorPos.top ?? 0) +
			parseCoord(record.offsetY, 0);
		left =
			parseCoord(record.left, anchorPos.left ?? 0) +
			parseCoord(record.offsetX, 0);
	} else {
		top = (anchorPos.top ?? 0) + parseCoord(record.offsetY, 0);
		left = (anchorPos.left ?? 0) + parseCoord(record.offsetX, 0);
	}

	if (anchor && isClosingLayoutAnchor(anchor)) {
		top = migrateClosingAssetTopFromPageAbsolute(top, margins);
	}

	return { top, left };
}

export function toCanvasDisplayPosition(
	anchor: LayoutPositionAnchor,
	position: LayoutPositionValue,
	margins: LetterPageMarginsPx = DEFAULT_LETTER_PAGE_MARGINS_PX,
): LayoutPositionValue {
	const top = position.top ?? 0;
	const left = position.left ?? 0;
	if (isClosingLayoutAnchor(anchor)) {
		return {
			...position,
			top: closingAssetToCanvasTop(top, margins),
			left,
		};
	}
	return { ...position, top, left };
}

export function fromCanvasDisplayPosition(
	anchor: LayoutPositionAnchor,
	position: LayoutPositionValue,
	margins: LetterPageMarginsPx = DEFAULT_LETTER_PAGE_MARGINS_PX,
): LayoutPositionValue {
	const top = position.top ?? 0;
	const left = position.left ?? 0;
	if (isClosingLayoutAnchor(anchor)) {
		return {
			...position,
			top: closingAssetFromCanvasTop(top, margins),
			left,
		};
	}
	return { ...position, top, left };
}

export function toAbsolutePayloadPosition(
	position: LayoutPositionValue,
): Record<string, unknown> {
	return {
		mode: "absolute",
		top: position.top ?? 0,
		left: position.left ?? 0,
		offsetX: 0,
		offsetY: 0,
	};
}

export function getLetterCanvasSize(
	margins: LetterPageMarginsPx = DEFAULT_LETTER_PAGE_MARGINS_PX,
) {
	return computeLetterContentAreaPx(margins);
}

export function buildDefaultClosingLanguagePositions(
	language: LetterLanguage,
	margins: LetterPageMarginsPx = DEFAULT_LETTER_PAGE_MARGINS_PX,
) {
	return {
		signatures: normalizeLayoutPositionValue(
			null,
			"signatures",
			margins,
			language,
		),
		seal: normalizeLayoutPositionValue(null, "seal", margins, language),
		stamp: normalizeLayoutPositionValue(null, "stamp", margins, language),
	};
}

export function buildDefaultPositionsByLanguage(
	margins: LetterPageMarginsPx = DEFAULT_LETTER_PAGE_MARGINS_PX,
) {
	return {
		am: buildDefaultClosingLanguagePositions("am", margins),
		en: buildDefaultClosingLanguagePositions("en", margins),
	};
}
