#!/usr/bin/env python3
"""
MiniBook - A tool to create a minibook from a list of links.
Supports both MkDocs and Jinja2/HTML generation.
"""

import os
from datetime import datetime

import typer
import yaml
from jinja2 import Environment, FileSystemLoader


def generate_html(title, links, description=None, timestamp=None, output_file="minibook.html"):
    """
    Generate an HTML page with the given title and links using Jinja2.

    Args:
        title (str): The title of the webpage
        links (list): A list of tuples with (name, url)
        description (str, optional): A description to include on the page
        timestamp (str, optional): A fixed timestamp for testing purposes
        output_file (str, optional): The output HTML file

    Returns:
        str: The path to the generated HTML file
    """
    # Set up Jinja2 environment
    template_dir = os.path.join(os.path.dirname(__file__), "templates")
    env = Environment(loader=FileSystemLoader(template_dir))
    template = env.get_template("html.j2")

    # Use the provided timestamp or generate a new one
    if timestamp is None:
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # Render the template with our data
    html = template.render(title=title, links=links, description=description, timestamp=timestamp)

    # Save the HTML to a file
    with open(output_file, "w") as f:
        f.write(html)

    return output_file


def generate_mkdocs_project(title, links, description=None, timestamp=None, output_dir="minibook_site"):
    """
    Generate a MkDocs project with the given title and links.

    Args:
        title (str): The title of the webpage
        links (list): A list of tuples with (name, url)
        description (str, optional): A description to include on the page
        timestamp (str, optional): A fixed timestamp for testing purposes
        output_dir (str, optional): The directory to create the MkDocs project in

    Returns:
        str: The path to the generated MkDocs project
    """
    # Create the output directory if it doesn't exist
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    # Create the docs directory
    docs_dir = os.path.join(output_dir, "docs")
    if not os.path.exists(docs_dir):
        os.makedirs(docs_dir)

    # Use the provided timestamp or generate a new one
    if timestamp is None:
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

    # Create the index.md file
    index_content = f"# {title}\n\n"

    if description:
        index_content += f"*{description}*\n\n"

    index_content += "## Links\n\n"

    for name, url in links:
        index_content += f"* [{name}]({url})\n"

    index_content += f"\n\n*Generated by MiniBook on {timestamp}*\n"

    with open(os.path.join(docs_dir, "index.md"), "w") as f:
        f.write(index_content)

    # Create the mkdocs.yml file
    mkdocs_config = {"site_name": title, "theme": "material", "nav": [{"Home": "index.md"}]}

    with open(os.path.join(output_dir, "mkdocs.yml"), "w") as f:
        yaml.dump(mkdocs_config, f, default_flow_style=False)

    return output_dir


app = typer.Typer(help="Create a minibook from a list of links")


@app.command()
def main(
    title: str = typer.Option("My Links", "--title", "-t", help="Title of the minibook"),
    description: str | None = typer.Option(None, "--description", "-d", help="Description of the minibook"),
    output: str = typer.Option("minibook.html", "--output", "-o", help="Output file or directory"),
    links: str = typer.Option(None, "--links", "-l", help="Comma-separated list of tuples with (name;url)"),
    timestamp: str | None = typer.Option(None, "--timestamp", help="Fixed timestamp for testing purposes"),
    format: str = typer.Option(
        "html", "--format", help="Output format: html or mkdocs", show_choices=True, case_sensitive=False
    ),
) -> int:
    """Create a minibook from a list of links."""
    if format not in ["html", "mkdocs"]:
        typer.echo(f"Invalid format: {format}. Must be 'html' or 'mkdocs'.", err=True)
        return 1

    pairs = links.split(",")

    typer.echo(f"pairs: {pairs}")

    links_tuples = []

    for pair in pairs:
        typer.echo(f"pair: {pair}")

        try:
            name, url = pair.strip().split(";")
            if not name or not url:
                raise ValueError(f"Invalid pair: {pair}")
            links_tuples.append((name.strip(), url.strip()))
        except ValueError as e:
            raise ValueError(f"Invalid link format: {pair}. Expected 'name;url'") from e

    # links_tuples = [(name, url) for name,url in pairs.split(";")]  # (name, url) tuples
    typer.echo(f"links_tuples: {links_tuples}")

    if not links_tuples:
        typer.echo("No links provided. Exiting.", err=True)
        return 1

    if format == "html":
        # Generate HTML using Jinja2
        output_file = output
        if os.path.isdir(output_file):
            output_file = os.path.join(output_file, "minibook.html")

        output_path = generate_html(title, links_tuples, description, timestamp, output_file)
        typer.echo(f"HTML minibook created successfully: {os.path.abspath(output_path)}")
    else:
        # Generate MkDocs project
        output_dir = output
        if output_dir.endswith(".html"):
            # If the output is specified as an HTML file but format is mkdocs,
            # use a default directory name
            output_dir = "minibook_site"

        output_path = generate_mkdocs_project(title, links_tuples, description, timestamp, output_dir)
        typer.echo(f"MkDocs minibook created successfully: {os.path.abspath(output_path)}")
        typer.echo(f"To build the site, run: cd {output_path} && mkdocs build")
        typer.echo(f"To serve the site locally, run: cd {output_path} && mkdocs serve")

    return 0


if __name__ == "__main__":
    app()
