// Render Edra/BlockNote JSON content to HTML
export const renderEdraContent = (content: any, options: { albumSlug?: string } = {}): string => {
	if (!content) return ''

	// Handle Tiptap format first (has type: 'doc')
	if (content.type === 'doc' && content.content) {
		return renderTiptapContent(content)
	}

	// Handle both { blocks: [...] } and { content: [...] } formats
	const blocks = content.blocks || content.content || []
	if (!Array.isArray(blocks)) return ''

	const renderBlock = (block: any): string => {
		switch (block.type) {
			case 'heading': {
				const level = block.attrs?.level || block.level || 1
				const headingText = block.content || block.text || ''
				return `<h${level}>${headingText}</h${level}>`
			}

			case 'paragraph': {
				const paragraphText = block.content || block.text || ''
				if (!paragraphText) return '<p><br></p>'
				return `<p>${paragraphText}</p>`
			}

			case 'bulletList':
			case 'ul': {
				const listItems = (block.content || [])
					.map((item: any) => {
						const itemText = item.content || item.text || ''
						return `<li>${itemText}</li>`
					})
					.join('')
				return `<ul>${listItems}</ul>`
			}

			case 'orderedList':
			case 'ol': {
				const orderedItems = (block.content || [])
					.map((item: any) => {
						const itemText = item.content || item.text || ''
						return `<li>${itemText}</li>`
					})
					.join('')
				return `<ol>${orderedItems}</ol>`
			}

			case 'blockquote': {
				const quoteText = block.content || block.text || ''
				return `<blockquote><p>${quoteText}</p></blockquote>`
			}

			case 'codeBlock':
			case 'code': {
				const codeText = block.content || block.text || ''
				const language = block.attrs?.language || block.language || ''
				return `<pre><code class="language-${language}">${codeText}</code></pre>`
			}

			case 'image': {
				const src = block.attrs?.src || block.src || ''
				const alt = block.attrs?.alt || block.alt || ''
				const caption = block.attrs?.caption || block.caption || ''

				// Check if we have a media ID stored in attributes first
				const mediaId = block.attrs?.mediaId || block.mediaId || extractMediaIdFromUrl(src)

				if (mediaId) {
					// Use album context for URL if available
					const photoUrl = options.albumSlug
						? `/photos/${options.albumSlug}/${mediaId}`
						: `/photos/p/${mediaId}`
					return `<figure class="interactive-figure"><a href="${photoUrl}" class="photo-link"><img src="${src}" alt="${alt}" /></a>${caption ? `<figcaption>${caption}</figcaption>` : ''}</figure>`
				} else {
					return `<figure><img src="${src}" alt="${alt}" />${caption ? `<figcaption>${caption}</figcaption>` : ''}</figure>`
				}
			}

			case 'hr':
			case 'horizontalRule':
				return '<hr>'

			default: {
				// For simple text content
				const text = block.content || block.text || ''
				if (text) {
					return `<p>${text}</p>`
				}
				return ''
			}
		}
	}

	return blocks.map(renderBlock).join('')
}

// Render Tiptap JSON content to HTML
function renderTiptapContent(doc: any): string {
	if (!doc || !doc.content) return ''

	const renderNode = (node: any): string => {
		switch (node.type) {
			case 'paragraph': {
				const content = renderInlineContent(node.content || [])
				if (!content) return '<p><br></p>'
				return `<p>${content}</p>`
			}

			case 'heading': {
				const level = node.attrs?.level || 1
				const content = renderInlineContent(node.content || [])
				return `<h${level}>${content}</h${level}>`
			}

			case 'bulletList': {
				const items = (node.content || [])
					.map((item: any) => {
						const itemContent = item.content?.map(renderNode).join('') || ''
						return `<li>${itemContent}</li>`
					})
					.join('')
				return `<ul>${items}</ul>`
			}

			case 'orderedList': {
				const items = (node.content || [])
					.map((item: any) => {
						const itemContent = item.content?.map(renderNode).join('') || ''
						return `<li>${itemContent}</li>`
					})
					.join('')
				return `<ol>${items}</ol>`
			}

			case 'listItem': {
				// List items are handled by their parent list
				return node.content?.map(renderNode).join('') || ''
			}

			case 'blockquote': {
				const content = node.content?.map(renderNode).join('') || ''
				return `<blockquote>${content}</blockquote>`
			}

			case 'codeBlock': {
				const language = node.attrs?.language || ''
				const content = node.content?.[0]?.text || ''
				return `<pre><code class="language-${language}">${escapeHtml(content)}</code></pre>`
			}

			case 'image': {
				const src = node.attrs?.src || ''
				const alt = node.attrs?.alt || ''
				const title = node.attrs?.title || ''
				const width = node.attrs?.width
				const height = node.attrs?.height
				const widthAttr = width ? ` width="${width}"` : ''
				const heightAttr = height ? ` height="${height}"` : ''

				// Check if we have a media ID stored in attributes first
				const mediaId = node.attrs?.mediaId || extractMediaIdFromUrl(src)

				if (mediaId) {
					// Always use direct photo permalink
					const photoUrl = `/photos/${mediaId}`
					return `<figure class="interactive-figure"><a href="${photoUrl}" class="photo-link"><img src="${src}" alt="${alt}"${widthAttr}${heightAttr} /></a>${title ? `<figcaption>${title}</figcaption>` : ''}</figure>`
				} else {
					return `<figure><img src="${src}" alt="${alt}"${widthAttr}${heightAttr} />${title ? `<figcaption>${title}</figcaption>` : ''}</figure>`
				}
			}

			case 'horizontalRule': {
				return '<hr>'
			}

			case 'hardBreak': {
				return '<br>'
			}

			case 'urlEmbed': {
				const url = node.attrs?.url || ''
				const title = node.attrs?.title || ''
				const description = node.attrs?.description || ''
				const image = node.attrs?.image || ''
				const favicon = node.attrs?.favicon || ''
				const siteName = node.attrs?.siteName || ''

				// Helper to get domain from URL
				const getDomain = (url: string) => {
					try {
						const urlObj = new URL(url)
						return urlObj.hostname.replace('www.', '')
					} catch {
						return ''
					}
				}

				// Helper to extract YouTube video ID
				const getYouTubeVideoId = (url: string): string | null => {
					const patterns = [
						/(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([^&\n?#]+)/,
						/youtube\.com\/watch\?.*v=([^&\n?#]+)/
					]

					for (const pattern of patterns) {
						const match = url.match(pattern)
						if (match && match[1]) {
							return match[1]
						}
					}
					return null
				}

				// Check if it's a YouTube URL
				const isYouTube = /(?:youtube\.com|youtu\.be)/.test(url)
				const videoId = isYouTube ? getYouTubeVideoId(url) : null

				if (isYouTube && videoId) {
					// Render YouTube embed
					let embedHtml = '<div class="url-embed-rendered url-embed-youtube">'
					embedHtml += '<div class="youtube-embed-wrapper">'
					embedHtml += `<iframe src="https://www.youtube.com/embed/${videoId}" `
					embedHtml += 'frameborder="0" '
					embedHtml +=
						'allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" '
					embedHtml += 'allowfullscreen>'
					embedHtml += '</iframe>'
					embedHtml += '</div>'
					embedHtml += '</div>'
					return embedHtml
				}

				// Regular URL embed for non-YouTube links
				let embedHtml = '<div class="url-embed-rendered">'
				embedHtml += `<a href="${url}" target="_blank" rel="noopener noreferrer" class="url-embed-link">`

				if (image) {
					embedHtml += `<div class="url-embed-image"><img src="${image}" alt="${title || 'Link preview'}" /></div>`
				}

				embedHtml += '<div class="url-embed-text">'
				embedHtml += '<div class="url-embed-meta">'
				if (favicon) {
					embedHtml += `<img src="${favicon}" alt="" class="url-embed-favicon" />`
				}
				embedHtml += `<span class="url-embed-domain">${siteName || getDomain(url)}</span>`
				embedHtml += '</div>'

				if (title) {
					embedHtml += `<h3 class="url-embed-title">${title}</h3>`
				}

				if (description) {
					embedHtml += `<p class="url-embed-description">${description}</p>`
				}

				embedHtml += '</div>'
				embedHtml += '</a>'
				embedHtml += '</div>'

				return embedHtml
			}

			default: {
				// For any unknown block types, try to render their content
				if (node.content) {
					return node.content.map(renderNode).join('')
				}
				return ''
			}
		}
	}

	// Render inline content (text nodes with marks)
	const renderInlineContent = (content: any[]): string => {
		return content
			.map((node: any) => {
				if (node.type === 'text') {
					let text = escapeHtml(node.text || '')

					// Apply marks (bold, italic, etc.)
					if (node.marks) {
						node.marks.forEach((mark: any) => {
							switch (mark.type) {
								case 'bold':
									text = `<strong>${text}</strong>`
									break
								case 'italic':
									text = `<em>${text}</em>`
									break
								case 'underline':
									text = `<u>${text}</u>`
									break
								case 'strike':
									text = `<s>${text}</s>`
									break
								case 'code':
									text = `<code>${text}</code>`
									break
								case 'link':
									const href = mark.attrs?.href || '#'
									const target = mark.attrs?.target || '_blank'
									text = `<a href="${href}" target="${target}" rel="noopener noreferrer">${text}</a>`
									break
								case 'highlight':
									text = `<mark>${text}</mark>`
									break
							}
						})
					}

					return text
				}

				// Handle other inline nodes
				return renderNode(node)
			})
			.join('')
	}

	// Helper to escape HTML
	const escapeHtml = (str: string): string => {
		return str
			.replace(/&/g, '&amp;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;')
			.replace(/"/g, '&quot;')
			.replace(/'/g, '&#039;')
	}

	return doc.content.map(renderNode).join('')
}

// Extract text content from Edra JSON for excerpt
export const getContentExcerpt = (content: any, maxLength = 200): string => {
	if (!content) return ''

	// Handle Tiptap format first (has type: 'doc')
	if (content.type === 'doc' && content.content) {
		return extractTiptapText(content, maxLength)
	}

	// Handle both { blocks: [...] } and { content: [...] } formats
	const blocks = content.blocks || content.content || []
	if (!Array.isArray(blocks)) return ''

	const extractText = (node: any): string => {
		// For block-level content
		if (node.type && node.content && typeof node.content === 'string') {
			return node.content
		}
		// For inline content with text property
		if (node.text) return node.text
		// For nested content
		if (node.content && Array.isArray(node.content)) {
			return node.content.map(extractText).join(' ')
		}
		return ''
	}

	const text = blocks.map(extractText).join(' ').trim()
	if (text.length <= maxLength) return text
	return text.substring(0, maxLength).trim() + '...'
}

// Extract text from Tiptap content
function extractTiptapText(doc: any, maxLength: number): string {
	const extractFromNode = (node: any): string => {
		if (node.type === 'text') {
			return node.text || ''
		}

		if (node.content && Array.isArray(node.content)) {
			return node.content.map(extractFromNode).join(' ')
		}

		return ''
	}

	const text = doc.content.map(extractFromNode).join(' ').trim()
	if (text.length <= maxLength) return text
	return text.substring(0, maxLength).trim() + '...'
}

// Helper function to extract media ID from Cloudinary URL
function extractMediaIdFromUrl(url: string): string | null {
	if (!url) return null

	// Match Cloudinary URLs with media ID pattern
	// Example: https://res.cloudinary.com/jedmund/image/upload/v1234567890/media/123.jpg
	const cloudinaryMatch = url.match(/\/media\/(\d+)(?:\.|$)/)
	if (cloudinaryMatch) {
		return cloudinaryMatch[1]
	}

	// Fallback: try to extract numeric ID from filename
	const filenameMatch = url.match(/\/(\d+)\.[^/]*$/)
	if (filenameMatch) {
		return filenameMatch[1]
	}

	return null
}
