"""Main book build engine."""

from __future__ import annotations

import shutil
from pathlib import Path

import markdown
from jinja2 import Environment, FileSystemLoader, select_autoescape

from .config import BookConfig

# Enabled Markdown extensions
MD_EXTENSIONS = [
    "extra",
    "codehilite",
    "toc",
    "smarty",
    "nl2br",
    "sane_lists",
]

MD_EXTENSION_CONFIGS = {
    "codehilite": {"css_class": "highlight", "linenums": False},
    "toc": {"permalink": False},
    "smarty": {"smart_dashes": True, "smart_quotes": True, "smart_ellipses": True},
}


def render_markdown(text: str) -> str:
    """Convert Markdown text to HTML."""
    md = markdown.Markdown(
        extensions=MD_EXTENSIONS,
        extension_configs=MD_EXTENSION_CONFIGS,
        output_format="html5",
    )
    return md.convert(text)


def process_chapter(chapter_path: Path, chapter_title: str | None = None) -> dict:
    """Process a Markdown chapter and return its HTML content."""
    if not chapter_path.exists():
        raise FileNotFoundError(f"Chapter not found: {chapter_path}")

    raw_text = chapter_path.read_text(encoding="utf-8")

    # If no title was provided, try to extract it from the first heading
    if chapter_title is None:
        for line in raw_text.splitlines():
            stripped = line.strip()
            if stripped.startswith("# "):
                chapter_title = stripped.lstrip("# ").strip()
                break

    html_content = render_markdown(raw_text)

    return {
        "title": chapter_title or chapter_path.stem,
        "html": html_content,
        "source_file": chapter_path.name,
    }


def build_book(config: BookConfig, base_dir: Path, *, pdf: bool = False) -> Path:
    """
    Build the complete book and generate HTML output.

    Produces two outputs:
      - Print version (PagedJS) → {print_filename}.html (or .pdf when pdf=True)
      - Reader version (interactive) → {reader_filename}.html + reader.css + reader.js

    Args:
        config: Book configuration loaded from YAML.
        base_dir: Base directory containing the book files.
        pdf: If True, generate PDF from the print HTML and delete the intermediate HTML.

    Returns:
        Path to the generated reader HTML file.
    """
    # Process chapters
    chapters = []
    for i, ch_config in enumerate(config.chapters, start=1):
        chapter_path = base_dir / ch_config.file
        chapter_data = process_chapter(chapter_path, ch_config.title)
        chapter_data["number"] = i
        chapters.append(chapter_data)

    # Prepare output directory
    output_dir = base_dir / config.output.directory
    output_dir.mkdir(parents=True, exist_ok=True)

    # Process cover image — copy to output instead of embedding as base64
    cover_image_uri = None
    if config.cover.image:
        cover_path = base_dir / config.cover.image
        if cover_path.exists():
            cover_dest = output_dir / cover_path.name
            shutil.copy2(cover_path, cover_dest)
            cover_image_uri = cover_path.name

    # Load templates
    templates_dir = Path(__file__).parent / "templates"
    env = Environment(
        loader=FileSystemLoader(str(templates_dir)),
        autoescape=select_autoescape(["html"]),
    )

    template_context = dict(
        book=config,
        chapters=chapters,
        cover_image_uri=cover_image_uri,
    )

    # --- Print version (PagedJS) ---
    print_template = env.get_template("book.html.j2")
    print_html = print_template.render(**template_context)
    print_file = output_dir / f"{config.output.print_filename}.html"
    print_file.write_text(print_html, encoding="utf-8")

    # --- PDF generation (optional) ---
    if pdf:
        from .pdf import generate_pdf

        pdf_file = output_dir / f"{config.output.print_filename}.pdf"
        generate_pdf(print_file, pdf_file)
        print_file.unlink()
        print_href = f"{config.output.print_filename}.pdf"
    else:
        print_href = f"{config.output.print_filename}.html"

    # --- Reader version (interactive) ---
    reader_template = env.get_template("reader.html.j2")
    reader_html = reader_template.render(
        **template_context,
        print_href=print_href,
    )
    reader_file = output_dir / f"{config.output.reader_filename}.html"
    reader_file.write_text(reader_html, encoding="utf-8")

    # Copy reader static assets
    for asset in ("reader.css", "reader.js"):
        src = templates_dir / asset
        if src.exists():
            shutil.copy2(src, output_dir / asset)

    return reader_file


def init_skeleton(base_dir: Path, title: str = "Mi Libro", num_chapters: int = 3):
    """
    Create a new book project skeleton.

    Args:
        base_dir: Directory where the skeleton will be created.
        title: Book title.
        num_chapters: Number of initial chapters.
    """
    base_dir.mkdir(parents=True, exist_ok=True)

    # Create chapter files
    chapter_entries = []
    for i in range(1, num_chapters + 1):
        chapter_file = f"chapter-{i}.md"
        chapter_path = base_dir / chapter_file
        if not chapter_path.exists():
            chapter_path.write_text(
                f"# Chapter {i}\n\nWrite your chapter content here.\n",
                encoding="utf-8",
            )
        chapter_entries.append({"file": chapter_file, "title": f"Chapter {i}"})

    # Create mkbooks.yml
    import yaml

    book_config = {
        "book": {
            "title": title,
            "subtitle": "",
            "author": "Tu Nombre",
            "language": "es",
            "description": f"Descripción de {title}",
            "year": "2026",
            "dedication": "",
            "cover": {
                "title_color": "#ffffff",
                "background_color": "#1a1a2e",
            },
            "chapters": chapter_entries,
            "style": {
                "page": {
                    "size": "A5",
                    "margin_top": "20mm",
                    "margin_bottom": "25mm",
                    "margin_inner": "25mm",
                    "margin_outer": "20mm",
                },
                "font": {
                    "body_family": "Georgia, 'Times New Roman', serif",
                    "body_size": "11pt",
                    "heading_family": "'Helvetica Neue', Arial, sans-serif",
                    "chapter_title_size": "28pt",
                    "line_height": "1.6",
                },
                "drop_cap": True,
                "chapter_break": "always",
            },
            "output": {
                "directory": "output",
                "filename": "book",
                "open_browser": True,
            },
        }
    }

    yml_path = base_dir / "mkbooks.yml"
    if not yml_path.exists():
        with open(yml_path, "w", encoding="utf-8") as f:
            yaml.dump(
                book_config,
                f,
                default_flow_style=False,
                allow_unicode=True,
                sort_keys=False,
            )

    return yml_path
