import { getAllPosts } from './markdown'
import type { Post } from './types/frontmatter'

export interface TagInfo {
  name: string
  slug: string
  count: number
}

export interface TagWithPosts {
  tag: TagInfo
  posts: Post[]
}

export function slugifyTag(tag: string): string {
  return tag
    .toLowerCase()
    .replace(/[ăâ]/g, 'a')
    .replace(/[îï]/g, 'i')
    .replace(/[șş]/g, 's')
    .replace(/[țţ]/g, 't')
    .replace(/\s+/g, '-')
    .replace(/[^a-z0-9-]/g, '')
    .replace(/-+/g, '-')
    .replace(/^-|-$/g, '')
}

export async function getAllTags(): Promise<TagInfo[]> {
  const posts = await getAllPosts()
  const tagMap = new Map<string, number>()

  posts.forEach(post => {
    const tags = post.frontmatter.tags?.filter(Boolean) || []
    tags.forEach(tag => {
      const count = tagMap.get(tag) || 0
      tagMap.set(tag, count + 1)
    })
  })

  return Array.from(tagMap.entries())
    .map(([name, count]) => ({
      name,
      slug: slugifyTag(name),
      count,
    }))
    .sort((a, b) => b.count - a.count)
}

export async function getPostsByTag(tagSlug: string): Promise<Post[]> {
  const posts = await getAllPosts()

  return posts.filter(post => {
    const tags = post.frontmatter.tags?.filter(Boolean) || []
    return tags.some(tag => slugifyTag(tag) === tagSlug)
  })
}

export async function getTagInfo(tagSlug: string): Promise<TagInfo | null> {
  const allTags = await getAllTags()
  return allTags.find(tag => tag.slug === tagSlug) || null
}

export async function getPopularTags(limit = 10): Promise<TagInfo[]> {
  const allTags = await getAllTags()
  return allTags.slice(0, limit)
}

export async function getRelatedTags(tagSlug: string, limit = 5): Promise<TagInfo[]> {
  const posts = await getPostsByTag(tagSlug)
  const relatedTagMap = new Map<string, number>()

  posts.forEach(post => {
    const tags = post.frontmatter.tags?.filter(Boolean) || []
    tags.forEach(tag => {
      const slug = slugifyTag(tag)
      if (slug !== tagSlug) {
        const count = relatedTagMap.get(tag) || 0
        relatedTagMap.set(tag, count + 1)
      }
    })
  })

  return Array.from(relatedTagMap.entries())
    .map(([name, count]) => ({
      name,
      slug: slugifyTag(name),
      count,
    }))
    .sort((a, b) => b.count - a.count)
    .slice(0, limit)
}

export function validateTags(tags: any): string[] {
  if (!tags) return []

  if (!Array.isArray(tags)) {
    console.warn('Tags should be an array')
    return []
  }

  const validTags = tags.filter(tag => tag && typeof tag === 'string').slice(0, 3)

  if (tags.length > 3) {
    console.warn(`Too many tags provided (${tags.length}). Limited to first 3.`)
  }

  return validTags
}

export async function getTagCloud(): Promise<Array<TagInfo & { size: 'sm' | 'md' | 'lg' | 'xl' }>> {
  const tags = await getAllTags()
  if (tags.length === 0) return []

  const maxCount = Math.max(...tags.map(t => t.count))
  const minCount = Math.min(...tags.map(t => t.count))
  const range = maxCount - minCount || 1

  return tags.map(tag => {
    const normalized = (tag.count - minCount) / range
    let size: 'sm' | 'md' | 'lg' | 'xl'

    if (normalized < 0.25) size = 'sm'
    else if (normalized < 0.5) size = 'md'
    else if (normalized < 0.75) size = 'lg'
    else size = 'xl'

    return { ...tag, size }
  })
}
