import type { PostWithUri } from './at/fetch';

const LINE_HEIGHT = 20; // approx line height in px
const CHARS_PER_LINE = 66; // approx chars per line
const BASE_HEIGHT = 100; // header + footer + padding
const IMAGE_HEIGHT = 300; // constrained height for single images
const IMAGE_GRID_HEIGHT = 200; // height for grid of images
const VIDEO_HEIGHT = 300; // default video height
const LINK_CARD_HEIGHT = 100; // external link card
const QUOTE_FALLBACK_HEIGHT = 100; // fallback for quote

// idk this is dumb idk i hate virtual lists and shit bleh
export const estimatePostHeight = (post: PostWithUri | undefined | null, depth = 0): number => {
	if (!post) return 150; // default fallback if post is missing
	if (depth > 1) return 0; // prevent infinite recursion

	const record = post.record;
	let height = BASE_HEIGHT;

	// 1. text height
	if (record.text) {
		const lines = Math.ceil(record.text.length / CHARS_PER_LINE) || 1;
		// add a bit more for newlines if present
		const newlines = (record.text.match(/\n/g) || []).length;
		height += Math.max(lines, newlines + 1) * LINE_HEIGHT;
	}

	// 2. embeds
	if (record.embed) {
		const embed = record.embed;

		if (embed.$type === 'app.bsky.embed.images') {
			// images
			if (embed.images.length === 1) {
				const aspect = embed.images[0].aspectRatio;
				if (aspect) {
					// w / h = a  => h = w / a
					// assuming max width of ~500px in feed
					const calculatedHeight = 500 / (aspect.width / aspect.height);
					height += Math.min(calculatedHeight, 500); // clamp max height
				} else {
					height += IMAGE_HEIGHT;
				}
			} else {
				height += IMAGE_GRID_HEIGHT;
			}
		} else if (embed.$type === 'app.bsky.embed.video') {
			// video
			const aspect = embed.aspectRatio;
			if (aspect) {
				const calculatedHeight = 500 / (aspect.width / aspect.height);
				height += Math.min(calculatedHeight, 500);
			} else {
				height += VIDEO_HEIGHT;
			}
		} else if (embed.$type === 'app.bsky.embed.record') {
			// quote post
			height += QUOTE_FALLBACK_HEIGHT;
		} else if (embed.$type === 'app.bsky.embed.recordWithMedia') {
			// recordWithMedia
			// media part
			const media = embed.media;
			if (media.$type === 'app.bsky.embed.images') {
				height += media.images.length === 1 ? IMAGE_HEIGHT : IMAGE_GRID_HEIGHT;
			} else if (media.$type === 'app.bsky.embed.video') {
				height += VIDEO_HEIGHT;
			}
			// quote part
			height += QUOTE_FALLBACK_HEIGHT;
		} else if (embed.$type === 'app.bsky.embed.external') {
			height += LINK_CARD_HEIGHT;
		}
	}

	return Math.round(height);
};
