import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { mapSlugToFileSlug } from './slugs';

export interface PostFrontmatter {
  title: string;
  date: string;
  excerpt?: string;
  featuredImage?: string | null;
  category?: string;
  locale: string;
}

export interface PostMdx {
  slug: string;
  frontmatter: PostFrontmatter;
  content: string;
}

export async function getPostBySlug(slug: string, locale: string): Promise<PostMdx | null> {
  // Map translated slug to file slug
  const fileSlug = await mapSlugToFileSlug(slug, locale);
  const postsDir = path.join(process.cwd(), 'data', 'blog', locale);
  const filePath = path.join(postsDir, `${fileSlug}.mdx`);

  if (!fs.existsSync(filePath)) {
    return null;
  }

  const fileContent = fs.readFileSync(filePath, 'utf8');
  const { data, content } = matter(fileContent);

  return {
    slug: fileSlug,
    frontmatter: data as PostFrontmatter,
    content,
  };
}

export async function getAllPosts(locale: string): Promise<PostMdx[]> {
  const postsDir = path.join(process.cwd(), 'data', 'blog', locale);
  if (!fs.existsSync(postsDir)) return [];

  const files = fs.readdirSync(postsDir);
  const posts = files
    .filter((file) => file.endsWith('.mdx'))
    .map((file) => {
      const filePath = path.join(postsDir, file);
      const fileContent = fs.readFileSync(filePath, 'utf8');
      const { data, content } = matter(fileContent);
      return {
        slug: file.replace(/\.mdx$/, ''),
        frontmatter: data as PostFrontmatter,
        content,
      };
    })
    .sort(
      (a, b) => new Date(b.frontmatter.date).getTime() - new Date(a.frontmatter.date).getTime(),
    );

  return posts;
}

export async function getAllPostsMetadata(locale: string): Promise<Partial<PostMdx>[]> {
  const postsDir = path.join(process.cwd(), 'data', 'blog', locale);
  if (!fs.existsSync(postsDir)) return [];

  const files = fs.readdirSync(postsDir);
  return files
    .filter((file) => file.endsWith('.mdx'))
    .map((file) => {
      const filePath = path.join(postsDir, file);
      const fileContent = fs.readFileSync(filePath, 'utf8');
      const { data } = matter(fileContent);
      return {
        slug: file.replace(/\.mdx$/, ''),
        frontmatter: data as PostFrontmatter,
      };
    })
    .sort(
      (a, b) =>
        new Date(b.frontmatter.date as string).getTime() -
        new Date(a.frontmatter.date as string).getTime(),
    );
}

export async function getAdjacentPosts(
  slug: string,
  locale: string,
): Promise<{ prev: PostMdx | null; next: PostMdx | null }> {
  const posts = await getAllPosts(locale);
  const currentIndex = posts.findIndex((post) => post.slug === slug);

  if (currentIndex === -1) {
    return { prev: null, next: null };
  }

  // Posts are sorted by date descending (newest first)
  // So "next" post (newer) is at index - 1
  // And "previous" post (older) is at index + 1
  const next = currentIndex > 0 ? posts[currentIndex - 1] : null;
  const prev = currentIndex < posts.length - 1 ? posts[currentIndex + 1] : null;

  return { prev, next };
}

export function getReadingTime(content: string): number {
  const wordsPerMinute = 200;
  const noOfWords = content.split(/\s/g).length;
  const minutes = noOfWords / wordsPerMinute;
  return Math.ceil(minutes);
}

export function getHeadings(content: string): { id: string; text: string; level: number }[] {
  const headingLines = content.split('\n').filter((line) => line.match(/^#{2,3}\s/));

  return headingLines.map((line) => {
    const level = line.match(/^#+/)?.[0].length || 0;
    const text = line.replace(/^#+\s/, '').trim();
    const id = text
      .toLowerCase()
      .replace(/[^\w\s-]/g, '')
      .replace(/\s+/g, '-');

    return { id, text, level };
  });
}
