#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Timestamp: 2026-02-08
# File: src/scitex_writer/_compile/content.py

"""Content/preview compilation for LaTeX snippets.

Compiles raw LaTeX content to PDF using the shell scripts layer:
  scripts/python/tex_snippet2full.py → builds .tex document
  scripts/shell/compile_content.sh → compiles to PDF via latexmk
"""

from __future__ import annotations

import subprocess
import tempfile
from pathlib import Path
from typing import Literal, Optional


def _get_scripts_dir(project_dir: Optional[str] = None) -> Path:
    """Get the scripts directory, preferring package scripts over project.

    Search order:
    1. repo/scripts/ (development mode - always up to date)
    2. package/_scripts/ (installed package fallback)
    3. project_dir/scripts/ (user's project - may be from old template)
    """
    # First priority: package/development scripts (always up to date)
    pkg_dir = Path(__file__).resolve().parent.parent  # src/scitex_writer/
    for candidate in [
        pkg_dir.parent.parent / "scripts",  # development: repo/scripts/
        pkg_dir / "_scripts",  # installed package fallback
    ]:
        if candidate.exists() and (candidate / "shell").exists():
            return candidate

    # Fallback: project's own scripts directory (may be outdated clone)
    if project_dir:
        proj_scripts = Path(project_dir) / "scripts"
        if proj_scripts.exists() and (proj_scripts / "shell").exists():
            return proj_scripts

    raise FileNotFoundError("Cannot find scripts directory")


def compile_content(
    latex_content: str,
    project_dir: Optional[str] = None,
    color_mode: Literal["light", "dark"] = "light",
    name: str = "content",
    timeout: int = 60,
    keep_aux: bool = False,
) -> dict:
    """Compile raw LaTeX content to PDF.

    Creates a standalone document from the provided LaTeX content and compiles
    it to PDF. Supports light/dark color modes for comfortable viewing.

    Parameters
    ----------
    latex_content : str
        Raw LaTeX content. Can be a complete document (with \\documentclass)
        or body-only content (will be wrapped automatically).
    project_dir : str, optional
        Path to scitex-writer project. If provided, PDF is copied to
        the project's .preview/ directory.
    color_mode : str
        Color theme: 'light' (default) or 'dark' (Monaco #1E1E1E).
    name : str
        Output filename (without extension).
    timeout : int
        Compilation timeout in seconds.
    keep_aux : bool
        Keep auxiliary files after compilation.

    Returns
    -------
    dict
        Result with keys: success, output_pdf, temp_dir, color_mode,
        log, message/error.
    """
    # Sanitize name: strip .tex extension if present
    if name.endswith(".tex"):
        name = name[:-4]

    try:
        scripts_dir = _get_scripts_dir(project_dir)
        doc_builder = scripts_dir / "python" / "tex_snippet2full.py"
        compiler = scripts_dir / "shell" / "compile_content.sh"

        temp_dir = Path(tempfile.mkdtemp(prefix=f"scitex_content_{name}_"))
        body_file = temp_dir / "body.tex"
        tex_file = temp_dir / f"{name}.tex"
        pdf_file = temp_dir / f"{name}.pdf"

        # Write body content
        body_file.write_text(latex_content, encoding="utf-8")

        # Step 1: Build complete LaTeX document
        is_complete = "\\documentclass" in latex_content
        build_cmd = [
            "python3",
            str(doc_builder),
            "--body-file",
            str(body_file),
            "--output",
            str(tex_file),
            "--color-mode",
            color_mode,
        ]
        if is_complete:
            build_cmd.append("--complete-document")

        build_result = subprocess.run(
            build_cmd,
            capture_output=True,
            text=True,
            timeout=30,
        )
        if build_result.returncode != 0:
            return {
                "success": False,
                "output_pdf": None,
                "error": f"Document build failed: {build_result.stderr}",
            }

        # Step 2: Compile to PDF
        compile_cmd = [
            "bash",
            str(compiler),
            "--tex-file",
            str(tex_file),
            "--output-dir",
            str(temp_dir),
            "--job-name",
            name,
            "--timeout",
            str(timeout),
        ]
        if keep_aux:
            compile_cmd.append("--keep-aux")
        compile_cmd.append("--quiet")

        # Add preview dir if project_dir is provided
        preview_dir = None
        if project_dir:
            preview_dir = Path(project_dir).resolve() / ".preview"
            compile_cmd.extend(["--preview-dir", str(preview_dir)])

        compile_result = subprocess.run(
            compile_cmd,
            capture_output=True,
            text=True,
            timeout=timeout + 10,
        )

        # Read log file
        log_content = _read_log(temp_dir, name)

        # Determine final PDF path
        final_pdf = pdf_file
        if compile_result.returncode == 0 and preview_dir:
            preview_pdf = preview_dir / f"{name}.pdf"
            if preview_pdf.exists():
                final_pdf = preview_pdf

        if compile_result.returncode == 0 and pdf_file.exists():
            return {
                "success": True,
                "output_pdf": str(final_pdf),
                "temp_dir": str(temp_dir),
                "color_mode": color_mode,
                "log": log_content,
                "message": f"Content compiled successfully: {name}",
            }
        else:
            return {
                "success": False,
                "output_pdf": None,
                "temp_dir": str(temp_dir),
                "color_mode": color_mode,
                "log": log_content,
                "stdout": _truncate(compile_result.stdout),
                "stderr": _truncate(compile_result.stderr),
                "error": f"Compilation failed with exit code {compile_result.returncode}",
            }

    except subprocess.TimeoutExpired:
        return {
            "success": False,
            "error": f"Content compilation timed out after {timeout} seconds",
        }
    except Exception as e:
        return {
            "success": False,
            "error": str(e),
        }


def _read_log(temp_dir: Path, name: str) -> str:
    """Read and truncate log file."""
    log_file = temp_dir / f"{name}.log"
    if log_file.exists():
        content = log_file.read_text(encoding="utf-8", errors="replace")
        return content[-5000:] if len(content) > 5000 else content
    return ""


def _truncate(text: str, limit: int = 2000) -> str:
    """Truncate text to limit."""
    return text[-limit:] if len(text) > limit else text


__all__ = ["compile_content"]

# EOF
