#!/usr/bin/env python3
"""Static site generator for SciSiteForge."""

from __future__ import annotations

import argparse
from pathlib import Path
import sys
from typing import Any

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from scisiteforge.config import DEFAULT_THEME, load_config, save_config
from scisiteforge.content import (
    SiteContent,
    cards_from_config,
    load_citegeist_cards,
    load_didactopus_cards,
    load_doclift_cards,
    load_groundrecall_cards,
)
from scisiteforge.render import html_escape, read_text, render_template, write_text
from scisiteforge.notebook import load_notebooks, render_notebooks
from scisiteforge.themes import available_themes, get_theme, materialize_theme


def _prompt_for_config() -> dict[str, Any]:
    print("=== SciSiteForge Site Config ===")
    themes = available_themes()
    print("Available themes:")
    for theme in themes:
        print(f"  - {theme.name}: {theme.description}")
    theme_name = input(f"Theme name (default: {DEFAULT_THEME}): ").strip() or DEFAULT_THEME
    languages_input = input("Languages (code:name pairs, comma-separated; default: en:English): ").strip() or "en:English"
    languages = []
    for pair in languages_input.split(","):
        code, name = pair.strip().split(":", 1)
        languages.append({"code": code.strip(), "name": name.strip()})
    return {
        "lang": input("Language code (default: en): ").strip() or "en",
        "title": input("Page title (default: SciSiteForge Preview): ").strip() or "SciSiteForge Preview",
        "site_title": input("Site name (default: SciSiteForge): ").strip() or "SciSiteForge",
        "license": input("License text (default: CC BY-SA 4.0): ").strip() or "CC BY-SA 4.0",
        "github_url": input("GitHub URL (optional): ").strip() or "https://github.com/",
        "contact_email": input("Contact email (optional): ").strip() or "admin@example.org",
        "theme": theme_name,
        "languages": languages,
        "navigation": [
            {"label": "Home", "href": "/"},
        ],
        "hero": {
            "kicker": "Preview",
            "title": "A site shell that can adapt to more than one audience.",
            "lede": "SciSiteForge now supports multiple theme presets and local content loaders for reusable science sites.",
            "actions": [
                {"label": "Read the overview", "href": "#overview", "primary": True},
                {"label": "Theme catalog", "href": "#themes", "primary": False},
            ],
        },
        "content_sources": {},
        "content": {},
        "notebooks": [],
    }


def _language_options_html(languages: list[dict[str, str]], current_lang: str) -> str:
    visible_languages = [
        item
        for item in languages
        if item.get("coverage", True) or item.get("code") == current_lang
    ]
    return "\n".join(
        f'<option value="{html_escape(item["code"])}" {"selected" if item["code"] == current_lang else ""}>{html_escape(item["name"])}</option>'
        for item in visible_languages
    )


def _language_policy_html(language_policy: dict[str, Any]) -> str:
    planned_languages = language_policy.get("planned_languages", [])
    if not planned_languages:
        return ""
    planned_names = ", ".join(html_escape(item.get("name", item.get("code", ""))) for item in planned_languages if item.get("name") or item.get("code"))
    if not planned_names:
        return ""
    return f'<p class="language-policy-note">Planned languages: {planned_names}</p>'


def _hero_actions_html(actions: list[dict[str, Any]]) -> str:
    if not actions:
        return ""
    return "\n".join(
        f'<a class="button-link{" button-link-secondary" if not action.get("primary") else ""}" href="{html_escape(action.get("href", "#"))}">{html_escape(action.get("label", "Open"))}</a>'
        for action in actions
    )


def _navigation_html(navigation: list[dict[str, str]]) -> str:
    return "\n".join(
        f'<a href="{html_escape(item.get("href", "#"))}">{html_escape(item.get("label", "Link"))}</a>'
        for item in navigation
    )


def _render_cards(cards: list, template_path: str | Path, lang: str) -> str:
    if not cards:
        return ""
    template = read_text(template_path)
    rendered: list[str] = []
    for card in cards:
        rendered.append(
            render_template(
                template,
                {
                    "lang": lang,
                    "app_title": html_escape(card.title),
                    "app_description": html_escape(card.body),
                    "app_slug": html_escape(card.source or card.title.lower().replace(" ", "-")),
                    "section_title": html_escape(card.title),
                    "section_meta": html_escape(card.meta),
                    "section_excerpt": html_escape(card.body),
                    "section_path": html_escape(card.source or card.title.lower().replace(" ", "-")),
                    "href": html_escape(card.href),
                    "link_label": "Open",
                },
            )
        )
    return "\n".join(rendered)


def build_site(config_file: str | Path, output_dir: str | Path) -> dict[str, Any]:
    config = load_config(config_file)
    theme = get_theme(config.get("theme"))
    out_path = Path(output_dir)
    out_path.mkdir(parents=True, exist_ok=True)

    theme_context = materialize_theme(theme, out_path)
    template = read_text(theme.template_path)

    content_sources = config.get("content_sources", {})
    site_content = SiteContent()
    if source := content_sources.get("doclift_bundle"):
        site_content.section_cards.extend(load_doclift_cards(source))
    if source := content_sources.get("groundrecall_bundle"):
        site_content.section_cards.extend(load_groundrecall_cards(source))
    if source := content_sources.get("didactopus_pack"):
        site_content.feature_cards.extend(load_didactopus_cards(source))
    if source := content_sources.get("bibliography"):
        site_content.bibliography_entries.extend(load_citegeist_cards(source))
    inline_content = config.get("content", {})
    site_content.feature_cards.extend(cards_from_config(inline_content.get("feature_cards", []), default_kind="feature"))
    site_content.section_cards.extend(cards_from_config(inline_content.get("section_cards", []), default_kind="section"))
    site_content.app_cards.extend(cards_from_config(inline_content.get("app_cards", []), default_kind="app"))
    site_content.bibliography_entries.extend(cards_from_config(inline_content.get("bibliography_entries", []), default_kind="bibliography"))
    notebooks = load_notebooks(config)

    languages = config.get("languages", [{"code": config.get("lang", "en"), "name": "English", "coverage": True}])
    language_policy = config.get("language_policy", {})
    hero = config.get("hero", {})
    page_context = {
        "lang": config.get("lang", "en"),
        "page_title": html_escape(config.get("title", config.get("site_title", "SciSiteForge"))),
        "site_title": html_escape(config.get("site_title", "SciSiteForge")),
        "description": html_escape(config.get("description", "")),
        "license": html_escape(config.get("license", "CC BY-SA 4.0")),
        "github_url": html_escape(config.get("github_url", "")),
        "contact_email": html_escape(config.get("contact_email", "")),
        "theme_name": html_escape(theme.name),
        "theme_display_name": html_escape(theme.display_name),
        "theme_description": html_escape(theme.description),
        "theme_stylesheet_href": theme_context["theme_stylesheet_href"],
        "theme_script_href": theme_context["theme_script_href"],
        "theme_asset_prefix": theme_context["theme_asset_prefix"],
        "body_class": html_escape(theme.body_class),
        "site_shell_class": html_escape(theme.shell_class),
        "page_class": html_escape(theme.page_class),
        "navigation_html": _navigation_html(config.get("navigation", [])),
        "language_options": _language_options_html(languages, config.get("lang", "en")),
        "language_policy_html": _language_policy_html(language_policy),
        "hero_kicker": html_escape(hero.get("kicker", theme.display_name)),
        "hero_title": html_escape(hero.get("title", config.get("title", ""))),
        "hero_lede": html_escape(hero.get("lede", config.get("description", ""))),
        "hero_actions_html": _hero_actions_html(hero.get("actions", [])),
        "feature_cards_html": _render_cards(site_content.feature_cards, Path(__file__).parent.parent / "templates" / "app-card.html", config.get("lang", "en")),
        "section_cards_html": _render_cards(site_content.section_cards, Path(__file__).parent.parent / "templates" / "notebook-section.html", config.get("lang", "en")),
        "app_cards_html": _render_cards(site_content.app_cards, Path(__file__).parent.parent / "templates" / "app-card.html", config.get("lang", "en")),
        "bibliography_html": "\n".join(
            f'<li><strong>{html_escape(card.title)}</strong> <span class="meta">{html_escape(card.body)}</span></li>'
            for card in site_content.bibliography_entries
        ),
        "notebook_html": render_notebooks(notebooks, site_content),
    }
    page_context.update(
        {
            "content_panels_html": page_context["feature_cards_html"] + "\n" + page_context["section_cards_html"],
        }
    )
    rendered = render_template(template, page_context)
    write_text(out_path / "index.html", rendered)
    return {"output_dir": str(out_path), "theme": theme.name, "theme_assets": theme_context["theme_assets"]}


def main() -> None:
    parser = argparse.ArgumentParser(description="Build a SciSiteForge site from a JSON config.")
    parser.add_argument("--init", action="store_true", help="Create site config interactively")
    parser.add_argument("--config", help="Path to site.json")
    parser.add_argument("--output", help="Output directory for built site")
    parser.add_argument("--themes", action="store_true", help="List the built-in theme presets")
    parser.add_argument("--save-config", help="Where to write the config when using --init", default="site.json")
    args = parser.parse_args()

    if args.themes:
        for theme in available_themes():
            print(f"{theme.name}: {theme.description}")
        return

    if args.init:
        config = _prompt_for_config()
        save_config(args.save_config, config)
        print(f"Wrote config to {args.save_config}")
        return

    if args.config and args.output:
        result = build_site(args.config, args.output)
        print(f"Built {result['output_dir']} with theme {result['theme']}")
        return

    parser.print_help()


if __name__ == "__main__":
    main()
