import type { MarkdownDocument } from './markdown-document';

export type MarkdownDocumentEntry = {
  id?: string;
  title?: string;
  folder?: string;
  path: string;
  order?: number;
  load: () => Promise<string>;
};

function extractTitle(markdown: string, fallback: string) {
  const heading = markdown.match(/^#\s+(.+)$/m);
  return heading?.[1]?.trim() || fallback;
}

function extractPreview(markdown: string) {
  const normalized = markdown
    .replace(/^#.+$/gm, '')
    .replace(/^##.+$/gm, '')
    .replace(/```[\s\S]*?```/g, '')
    .replace(/`/g, '')
    .replace(/\n+/g, ' ')
    .trim();

  return normalized.slice(0, 180);
}

export async function resolveMarkdownDocuments(
  entries: MarkdownDocumentEntry[],
  basePath?: string,
) {
  const filteredEntries = basePath
    ? entries.filter((entry) => entry.path.includes(basePath))
    : entries;

  const loadedDocuments = await Promise.all(
    filteredEntries.map(async (entry) => {
      const content = await entry.load();
      const fallback = entry.path.split('/').at(-1)?.replace(/\.md$/, '') || 'document';
      const relativePath = basePath ? entry.path.split(basePath)[1] || '' : entry.path;
      const folder = entry.folder ?? (relativePath.split('/').filter(Boolean)[0] || 'root');

      return {
        id: entry.id ?? entry.path.replace(/[^\w-]+/g, '-'),
        title: entry.title ?? extractTitle(content, fallback),
        preview: extractPreview(content),
        path: entry.path,
        content,
        folder,
      } satisfies MarkdownDocument;
    }),
  );

  return loadedDocuments.sort(
    (left, right) =>
      ((filteredEntries.find((entry) => entry.path === left.path)?.order ??
        Number.MAX_SAFE_INTEGER) -
        (filteredEntries.find((entry) => entry.path === right.path)?.order ??
          Number.MAX_SAFE_INTEGER)) ||
      left.title.localeCompare(right.title),
  );
}
