"""Load markdown posts with frontmatter and render to SEO-friendly HTML."""

# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/11_utils_blog.ipynb.

# %% ../nbs/11_utils_blog.ipynb #915e7626
from __future__ import annotations
import frontmatter
import markdown
from pathlib import Path
from typing import List, Dict, Optional
from datetime import datetime
from nbdev.showdoc import show_doc

# %% auto #0
__all__ = ['PostLoader', 'MarkdownEngine']

# %% ../nbs/11_utils_blog.ipynb #512f42da
def _generate_slug(filename: str) -> str:
    """Generate URL-safe slug from filename"""
    return filename.replace('.md', '').replace(' ', '-').lower()

def _parse_date(date_val: any) -> Optional[datetime]:
    """Parse date from frontmatter (handles datetime, str, None)"""
    if isinstance(date_val, datetime):
        return date_val
    if isinstance(date_val, str):
        try:
            return datetime.fromisoformat(date_val.replace('Z', '+00:00'))
        except:
            return None
    return None

# %% ../nbs/11_utils_blog.ipynb #d0012a94
class PostLoader:
    """Load and parse markdown blog posts from filesystem"""
    
    def __init__(self, posts_dir: str): # Directory containing .md files
        """Initialize PostLoader with posts directory"""
        self.posts_dir = Path(posts_dir)
    
    def load_posts(self) -> List[Dict]:
        """
        Load all markdown posts from directory.
        
        Returns list of post dicts sorted by date (newest first).
        Each post contains: title, date, slug, body, categories, author, series.
        
        Example:
            ```python
            loader = PostLoader('blog/posts')
            posts = loader.load_posts()
            
            for post in posts:
                print(f"{post['title']} - {post['slug']}")
            ```
        """
        posts = []
        
        if not self.posts_dir.exists():
            return posts
        
        for md_file in self.posts_dir.glob('*.md'):
            post = frontmatter.load(md_file)
            
            posts.append({
                'title': post.get('title', md_file.stem),
                'date': _parse_date(post.get('date')),
                'slug': _generate_slug(md_file.name),
                'body': post.content,
                'categories': post.get('categories', []),
                'author': post.get('author'),
                'series': post.get('series'),
                'description': post.get('description', ''),
                'image': post.get('image')
            })
        
        # Sort by date (newest first)
        posts.sort(key=lambda p: p['date'] or datetime.min, reverse=True)
        return posts
    
    def get_post(self, slug: str) -> Optional[Dict]: # URL slug (e.g., 'my-post')
        """
        Get single post by slug.
        
        Example:
            ```python
            post = loader.get_post('bg0010')
            if post:
                print(post['title'])
            ```
        """
        posts = self.load_posts()
        return next((p for p in posts if p['slug'] == slug), None)

# %% ../nbs/11_utils_blog.ipynb #3595b852
class MarkdownEngine:
    """Render markdown to HTML with SEO extensions"""
    
    def __init__(self):
        """Initialize markdown renderer with standard extensions"""
        self.md = markdown.Markdown(
            extensions=[
                'toc',           # Table of contents
                'fenced_code',   # ```code blocks```
                'tables',        # Markdown tables
                'codehilite',    # Syntax highlighting
                'extra'          # Abbreviations, definitions, etc.
            ],
            extension_configs={
                'codehilite': {
                    'css_class': 'highlight',
                    'linenums': False
                }
            }
        )
    
    def render(self, content: str) -> str: # Markdown content
        """
        Convert markdown to HTML.
        
        Returns HTML string with proper semantic tags for SEO.
        
        Example:
            ```python
            engine = MarkdownEngine()
            html = engine.render('# Hello\n\nThis is **bold**.')
            print(html)  # <h1>Hello</h1><p>This is <strong>bold</strong>.</p>
            ```
        """
        self.md.reset()  # Reset parser state
        return self.md.convert(content)
    
    def get_toc(self) -> str:
        """
        Get table of contents HTML from last render.
        
        Must call render() first. Returns empty string if no headings.
        
        Example:
            ```python
            engine = MarkdownEngine()
            html = engine.render('# Title\n## Section 1\n## Section 2')
            toc = engine.get_toc()
            print(toc)  # <ul><li><a href="#section-1">Section 1</a>...</li></ul>
            ```
        """
        return self.md.toc if hasattr(self.md, 'toc') else ''
