import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import readingTime from 'reading-time';
import { notFound } from 'next/navigation';

const postsDirectory = path.join(process.cwd(), 'posts');

export interface Heading {
  level: number;
  text: string;
  slug: string;
}

export interface PostData {
  id: string;
  date: string;
  title: string;
  description: string;
  content: string;
  readingTime: string;
  headings: Heading[];
  wip: boolean;
}

export interface PostMeta {
  id: string;
  date: string;
  title: string;
  description: string;
  readingTime: string;
  wip: boolean;
}

function extractHeadings(content: string): Heading[] {
  const regex = /^(#{1,3})\s+(.+)$/gm;
  const headings: Heading[] = [];
  let match;
  while ((match = regex.exec(content)) !== null) {
    const text = match[2].trim();
    const slug = text
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/(^-|-$)/g, '');
    headings.push({ level: match[1].length, text, slug });
  }
  return headings;
}

export function getSortedPostsData(): PostMeta[] {
  try {
    const fileNames = fs.readdirSync(postsDirectory);
    const allPostsData = fileNames
      .filter(fileName => fileName.endsWith('.mdx'))
      .map(fileName => {
        const id = fileName.replace(/\.mdx$/, '');
        const fullPath = path.join(postsDirectory, fileName);
        const fileContents = fs.readFileSync(fullPath, 'utf8');
        const matterResult = matter(fileContents);
        const stats = readingTime(matterResult.content);

        return {
          id,
          date: matterResult.data.date as string,
          title: matterResult.data.title as string,
          description: matterResult.data.description as string,
          readingTime: stats.text,
          wip: matterResult.data.wip ?? false,
        };
      });

    return allPostsData.sort((a, b) => (a.date < b.date ? 1 : -1));
  } catch (error) {
    console.log("No 'posts' directory found, returning empty array.");
    return [];
  }
}

export function getAllPostIds() {
  try {
    const fileNames = fs.readdirSync(postsDirectory);
    return fileNames.map(fileName => ({
      params: {
        slug: fileName.replace(/\.mdx$/, ''),
      },
    }));
  } catch (error) {
    return [];
  }
}

export function getAdjacentPosts(slug: string): { prev: PostMeta | null; next: PostMeta | null } {
  const posts = getSortedPostsData(); // newest → oldest
  const index = posts.findIndex((p) => p.id === slug);
  if (index === -1) return { prev: null, next: null };
  return {
    prev: posts[index + 1] ?? null, // older
    next: posts[index - 1] ?? null, // newer
  };
}

export async function getPostData(id: string): Promise<PostData> {
  const fullPath = path.join(postsDirectory, `${id}.mdx`);
  if (!fs.existsSync(fullPath)) notFound();
  const fileContents = fs.readFileSync(fullPath, 'utf8');
  const matterResult = matter(fileContents);
  const stats = readingTime(matterResult.content);

  return {
    id,
    content: matterResult.content,
    date: matterResult.data.date,
    title: matterResult.data.title,
    description: matterResult.data.description,
    readingTime: stats.text,
    headings: extractHeadings(matterResult.content),
    wip: matterResult.data.wip ?? false,
  };
}
