import { useMemo, useCallback } from 'react';
import { parse, stringify } from 'yaml';

export interface BlogFrontmatter {
  date?: string;
  authors?: string[];
  categories?: string[];
  tags?: string[];
  draft?: boolean;
  slug?: string;
  description?: string;
}

const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;

function parseFrontmatter(content: string): { frontmatter: BlogFrontmatter | null; body: string } {
  const match = content.match(FRONTMATTER_RE);
  if (!match) return { frontmatter: null, body: content };
  try {
    const parsed = parse(match[1] as string) as BlogFrontmatter | null;
    return { frontmatter: parsed ?? {}, body: (match[2] as string) ?? '' };
  } catch {
    return { frontmatter: null, body: content };
  }
}

function rebuildContent(frontmatter: BlogFrontmatter, body: string): string {
  const yamlStr = stringify(frontmatter, { lineWidth: 0 }).trimEnd();
  return `---\n${yamlStr}\n---\n${body}`;
}

interface UseBlogFrontmatterReturn {
  isBlogPost: boolean;
  frontmatter: BlogFrontmatter | null;
  updateFrontmatter: (field: string, value: unknown) => string;
}

export function useBlogFrontmatter(
  selectedFile: string | null,
  fileContent: string,
): UseBlogFrontmatterReturn {
  const isBlogPost = useMemo(
    () =>
      !!selectedFile &&
      selectedFile.startsWith('blog/posts/') &&
      selectedFile.endsWith('.md'),
    [selectedFile],
  );

  const { frontmatter, body } = useMemo(() => {
    if (!isBlogPost) return { frontmatter: null, body: fileContent };
    return parseFrontmatter(fileContent);
  }, [isBlogPost, fileContent]);

  const updateFrontmatter = useCallback(
    (field: string, value: unknown): string => {
      const current = frontmatter ?? {};
      const updated = { ...current, [field]: value };

      // Remove empty optional fields to keep frontmatter clean
      if (value === undefined || value === null || value === '') {
        delete (updated as Record<string, unknown>)[field];
      }
      if (Array.isArray(value) && value.length === 0) {
        delete (updated as Record<string, unknown>)[field];
      }

      return rebuildContent(updated, body);
    },
    [frontmatter, body],
  );

  return { isBlogPost, frontmatter, updateFrontmatter };
}
