#!/usr/bin/env python3
"""Build a styled HTML file from chapter markdown drafts for email/review."""

import argparse
import re
import sys
from pathlib import Path

import markdown


CHAPTER_DIR = Path(__file__).parent / "chapters" / "book1"
OUTPUT_DIR = Path(__file__).parent / "exports"

HTML_TEMPLATE = """\
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>The Floundry Affair - A Phelan Varrant Novel (Draft)</title>
<style>
  :root[data-theme="dark"] {{
    --bg: #1a1a2e;
    --text: #d4d4dc;
    --text-muted: #888899;
    --text-subtle: #6a6a7a;
    --border: #2a2a3e;
    --toggle-bg: #2a2a3e;
    --toggle-hover: #3a3a4e;
  }}
  :root[data-theme="light"] {{
    --bg: #fefefe;
    --text: #222;
    --text-muted: #555;
    --text-subtle: #888;
    --border: #ccc;
    --toggle-bg: #eee;
    --toggle-hover: #ddd;
  }}
  body {{
    max-width: 700px;
    margin: 40px auto;
    padding: 0 20px;
    font-family: Georgia, 'Times New Roman', serif;
    font-size: 18px;
    line-height: 1.8;
    color: var(--text);
    background: var(--bg);
    transition: color 0.3s, background 0.3s;
  }}
  h1 {{
    font-size: 28px;
    margin-top: 80px;
    margin-bottom: 30px;
    text-align: center;
    page-break-before: always;
  }}
  h1:first-of-type {{
    margin-top: 40px;
    page-break-before: avoid;
  }}
  p {{
    margin: 0 0 1em 0;
    text-indent: 1.5em;
  }}
  /* Scene breaks */
  p:has(> br:only-child), p:empty {{
    text-indent: 0;
  }}
  .scene-break {{
    text-align: center;
    margin: 2em 0;
    text-indent: 0 !important;
    letter-spacing: 0.5em;
    font-size: 14px;
  }}
  em {{ font-style: italic; }}
  strong {{ font-weight: bold; }}
  /* Title page */
  .title-page {{
    text-align: center;
    padding: 80px 0 60px;
    border-bottom: 1px solid var(--border);
    margin-bottom: 40px;
  }}
  .title-page h1 {{
    font-size: 36px;
    margin: 0 0 10px;
    page-break-before: avoid;
  }}
  .title-page .subtitle {{
    font-size: 22px;
    font-style: italic;
    color: var(--text-muted);
    margin: 0 0 30px;
  }}
  .title-page .draft-notice {{
    font-size: 14px;
    color: var(--text-subtle);
    margin-top: 20px;
  }}
  /* Table of contents */
  .toc {{
    max-width: 400px;
    margin: 0 auto 40px;
    padding: 20px 30px;
    border: 1px solid var(--border);
    border-radius: 8px;
  }}
  .toc h2 {{
    font-size: 18px;
    text-align: center;
    margin: 0 0 16px;
    color: var(--text-muted);
    font-variant: small-caps;
    letter-spacing: 0.1em;
  }}
  .toc ol {{
    list-style: none;
    padding: 0;
    margin: 0;
  }}
  .toc li {{
    margin: 8px 0;
  }}
  .toc a {{
    color: var(--text);
    text-decoration: none;
    font-size: 16px;
    transition: color 0.2s;
  }}
  .toc a:hover {{
    color: var(--text-muted);
    text-decoration: underline;
  }}
  /* First paragraph after heading shouldn't indent */
  h1 + p {{
    text-indent: 0;
  }}
  /* Theme toggle */
  .theme-toggle {{
    position: fixed;
    top: 16px;
    right: 16px;
    background: var(--toggle-bg);
    border: 1px solid var(--border);
    border-radius: 24px;
    padding: 6px 14px;
    cursor: pointer;
    font-size: 14px;
    font-family: sans-serif;
    color: var(--text-muted);
    transition: background 0.3s, color 0.3s, border-color 0.3s;
    z-index: 100;
  }}
  .theme-toggle:hover {{
    background: var(--toggle-hover);
  }}
  @media print {{
    .theme-toggle {{ display: none; }}
  }}
</style>
</head>
<body>
<button class="theme-toggle" onclick="toggleTheme()" aria-label="Toggle light/dark mode">
  <span id="theme-icon">&#9788;</span>
</button>
<div class="title-page">
  <h1>The Floundry Affair</h1>
  <div class="subtitle">A Phelan Varrant Novel — Book 1</div>
  <div class="draft-notice">DRAFT - Chapters {chapter_label} - For Review Only</div>
</div>
{toc}
{content}
<script>
function toggleTheme() {{
  var html = document.documentElement;
  var icon = document.getElementById('theme-icon');
  if (html.getAttribute('data-theme') === 'dark') {{
    html.setAttribute('data-theme', 'light');
    icon.textContent = '\\u263E';
  }} else {{
    html.setAttribute('data-theme', 'dark');
    icon.textContent = '\\u2606';
  }}
}}
</script>
</body>
</html>
"""


def parse_chapter_range(spec: str) -> list[int]:
    """Parse a chapter spec like '1-5' or '1,3,5' or '3' into a list of ints."""
    chapters = []
    for part in spec.split(","):
        part = part.strip()
        if "-" in part:
            start, end = part.split("-", 1)
            chapters.extend(range(int(start), int(end) + 1))
        else:
            chapters.append(int(part))
    return sorted(set(chapters))


def find_chapter_file(num: int) -> Path:
    """Find the best available file for a chapter number (prefer final, fall back to draft)."""
    final = CHAPTER_DIR / f"ch{num:02d}-final.md"
    draft = CHAPTER_DIR / f"ch{num:02d}-draft.md"
    if final.exists():
        return final
    if draft.exists():
        return draft
    return None


def convert_scene_breaks(html: str) -> str:
    """Replace bare '* * *' paragraphs with styled scene breaks."""
    html = html.replace("<p>* * *</p>", '<p class="scene-break">* * *</p>')
    return html


def extract_title(text: str) -> str:
    """Extract the chapter title from the first # heading in the markdown."""
    match = re.match(r"^#\s+(.+)$", text.strip(), re.MULTILINE)
    return match.group(1) if match else None


def add_heading_id(html: str, anchor_id: str) -> str:
    """Add an id attribute to the first <h1> tag in the HTML."""
    return html.replace("<h1>", f'<h1 id="{anchor_id}">', 1)


def build_toc(entries: list[tuple[str, str]]) -> str:
    """Build a table of contents HTML block from (anchor_id, title) pairs."""
    items = "\n".join(
        f'    <li><a href="#{aid}">{title}</a></li>' for aid, title in entries
    )
    return f'<nav class="toc">\n  <h2>Contents</h2>\n  <ol>\n{items}\n  </ol>\n</nav>'


def build(chapters: list[int]) -> str:
    """Combine and convert chapters to styled HTML."""
    md = markdown.Markdown(extensions=["smarty"])
    combined_html = []
    toc_entries = []

    for num in chapters:
        path = find_chapter_file(num)
        if path is None:
            print(f"Warning: No file found for chapter {num}, skipping.", file=sys.stderr)
            continue

        text = path.read_text(encoding="utf-8")

        title = extract_title(text)
        anchor_id = f"ch{num:02d}"

        if title:
            toc_entries.append((anchor_id, title))

        md.reset()
        html = md.convert(text)
        html = convert_scene_breaks(html)
        html = add_heading_id(html, anchor_id)
        combined_html.append(html)
        print(f"  Added: {path.name}")

    if not combined_html:
        print("Error: No chapters found.", file=sys.stderr)
        sys.exit(1)

    if len(chapters) == 1:
        chapter_label = str(chapters[0])
    else:
        chapter_label = f"{chapters[0]}-{chapters[-1]}"

    toc = build_toc(toc_entries) if len(toc_entries) > 1 else ""
    content = "\n\n".join(combined_html)
    return HTML_TEMPLATE.format(content=content, chapter_label=chapter_label, toc=toc)


def main():
    parser = argparse.ArgumentParser(description="Build HTML from chapter markdown drafts.")
    parser.add_argument(
        "-chapters",
        required=True,
        help="Chapter range: e.g. '1-5', '1,3,5', or '3'",
    )
    parser.add_argument(
        "-o", "--output",
        help="Output filename (default: auto-generated in exports/)",
    )
    args = parser.parse_args()

    chapters = parse_chapter_range(args.chapters)
    print(f"Building HTML for chapters: {chapters}")

    html = build(chapters)

    OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
    if args.output:
        out_path = Path(args.output)
    else:
        if len(chapters) == 1:
            label = f"ch{chapters[0]:02d}"
        else:
            label = f"ch{chapters[0]:02d}-{chapters[-1]:02d}"
        out_path = OUTPUT_DIR / f"book1-{label}-review.html"

    out_path.write_text(html, encoding="utf-8")
    print(f"Output: {out_path}")


if __name__ == "__main__":
    main()
