import type { FolkShape } from "./folk-shape";

interface StoredDimensions {
	x: number;
	y: number;
	width: number;
	height: number;
	rotation: number;
}

// Store original dimensions for each maximized shape
const originalDimensions = new WeakMap<FolkShape, StoredDimensions>();

/**
 * Check if a shape is currently maximized
 */
export function isMaximized(shape: FolkShape): boolean {
	return originalDimensions.has(shape);
}

/**
 * Maximize a shape to fill the viewport
 * @param shape - The shape to maximize
 * @param padding - Padding from viewport edges (default 40px)
 * @param animate - Whether to animate the transition (default true)
 */
export function maximizeShape(
	shape: FolkShape,
	padding = 40,
	animate = true
): void {
	if (isMaximized(shape)) {
		// Already maximized, restore instead
		restoreShape(shape, animate);
		return;
	}

	// Store original dimensions
	originalDimensions.set(shape, {
		x: shape.x,
		y: shape.y,
		width: shape.width,
		height: shape.height,
		rotation: shape.rotation,
	});

	// Calculate viewport dimensions
	const viewportWidth = window.innerWidth - padding * 2;
	const viewportHeight = window.innerHeight - padding * 2;

	// Get canvas element to account for any transforms
	const canvas = shape.closest("#canvas") as HTMLElement | null;
	const canvasRect = canvas?.getBoundingClientRect();
	const scrollX = window.scrollX || 0;
	const scrollY = window.scrollY || 0;

	// Calculate centered position
	const newX = padding + scrollX - (canvasRect?.left || 0);
	const newY = padding + scrollY - (canvasRect?.top || 0);

	if (animate) {
		shape.style.transition = "all 0.3s ease-out";
	}

	// Apply maximized dimensions
	shape.x = newX;
	shape.y = newY;
	shape.width = viewportWidth;
	shape.height = viewportHeight;
	shape.rotation = 0;

	// Add maximized state
	shape.setAttribute("data-maximized", "true");

	// Remove transition after animation
	if (animate) {
		setTimeout(() => {
			shape.style.transition = "";
		}, 300);
	}

	// Dispatch event
	shape.dispatchEvent(
		new CustomEvent("maximize", {
			detail: { maximized: true },
			bubbles: true,
		})
	);
}

/**
 * Restore a maximized shape to its original dimensions
 * @param shape - The shape to restore
 * @param animate - Whether to animate the transition (default true)
 */
export function restoreShape(shape: FolkShape, animate = true): void {
	const original = originalDimensions.get(shape);
	if (!original) return;

	if (animate) {
		shape.style.transition = "all 0.3s ease-out";
	}

	// Restore original dimensions
	shape.x = original.x;
	shape.y = original.y;
	shape.width = original.width;
	shape.height = original.height;
	shape.rotation = original.rotation;

	// Remove maximized state
	shape.removeAttribute("data-maximized");
	originalDimensions.delete(shape);

	// Remove transition after animation
	if (animate) {
		setTimeout(() => {
			shape.style.transition = "";
		}, 300);
	}

	// Dispatch event
	shape.dispatchEvent(
		new CustomEvent("maximize", {
			detail: { maximized: false },
			bubbles: true,
		})
	);
}

/**
 * Toggle maximize state of a shape
 * @param shape - The shape to toggle
 * @param padding - Padding from viewport edges (default 40px)
 * @param animate - Whether to animate the transition (default true)
 */
export function toggleMaximize(
	shape: FolkShape,
	padding = 40,
	animate = true
): void {
	if (isMaximized(shape)) {
		restoreShape(shape, animate);
	} else {
		maximizeShape(shape, padding, animate);
	}
}
