"""Generate a comprehensive Markdown analysis report from the Knowledge Graph.

This is a *premium* output format that combines deterministic parsing
with LLM-generated summaries into a single analyst-grade document.
"""

from __future__ import annotations

from pathlib import Path
from datetime import datetime

from ..core.knowledge_graph import EntityType, KnowledgeGraph
from ..core.models import DocumentModel, GenerationResult, OutputFormat


def generate_smart_report(
    doc: DocumentModel,
    kg: KnowledgeGraph,
    output_dir: Path,
) -> GenerationResult:
    """Generate a comprehensive Markdown analysis report.

    Parameters
    ----------
    doc
        Parsed document model.
    kg
        Populated knowledge graph (may include LLM summaries).
    output_dir
        Directory to write the report to.

    Returns
    -------
    GenerationResult
        Path and success status of the generated file.
    """
    name = doc.metadata.repo_name or "document"
    safe = "".join(c if c.isalnum() or c in "-_ " else "_" for c in name)
    safe = safe.strip().replace(" ", "_")[:80] or "document"
    output_path = output_dir / f"{safe}_analysis.md"

    try:
        content = _build_report(doc, kg)
        output_path.write_text(content, encoding="utf-8")
        return GenerationResult(
            format=OutputFormat.WORD,  # reuse enum — just a file result
            output_path=output_path,
        )
    except Exception as exc:
        return GenerationResult(
            format=OutputFormat.WORD,
            output_path=output_path,
            success=False,
            error=str(exc),
        )


def _build_report(doc: DocumentModel, kg: KnowledgeGraph) -> str:
    """Build the full Markdown report string."""
    lines: list[str] = []
    now = datetime.now().strftime("%Y-%m-%d %H:%M")

    # -- Header --
    lines.append(f"# {doc.metadata.repo_name or 'Project'} -- Semantic Analysis Report")
    lines.append("")
    lines.append(f"> Generated by **opendocs** on {now}")
    lines.append(f"> Source: `{doc.metadata.repo_url or doc.metadata.source_path or '—'}`")
    lines.append("")
    lines.append("---")
    lines.append("")

    # -- Executive Summary --
    if kg.executive_summary:
        lines.append("## Executive Summary")
        lines.append("")
        lines.append(kg.executive_summary)
        lines.append("")

    # -- Knowledge Graph Stats --
    stats = kg.extraction_stats or kg.compute_stats()
    lines.append("## Knowledge Graph Overview")
    lines.append("")
    lines.append("| Metric | Value |")
    lines.append("|--------|-------|")
    lines.append(f"| Total Entities | {stats.get('total_entities', 0)} |")
    lines.append(f"| Total Relations | {stats.get('total_relations', 0)} |")
    lines.append(f"| Deterministic | {stats.get('deterministic_entities', 0)} |")
    lines.append(f"| LLM-Extracted | {stats.get('llm_entities', 0)} |")

    # Entity type breakdown
    for et in EntityType:
        count = stats.get(f"entities_{et.value}", 0)
        if count:
            lines.append(f"| {et.value.replace('_', ' ').title()} | {count} |")
    lines.append("")

    # -- Stakeholder Summaries --
    persona_labels = {
        "cto": "CTO / Technical Lead Assessment",
        "investor": "Investor / Business Analysis",
        "developer": "Developer Onboarding Guide",
    }

    if kg.stakeholder_summaries:
        lines.append("## Stakeholder Views")
        lines.append("")
        for persona, content in kg.stakeholder_summaries.items():
            if not content or content.startswith("["):
                continue
            label = persona_labels.get(persona, persona.title())
            lines.append(f"### {label}")
            lines.append("")
            lines.append(content.strip())
            lines.append("")

    # -- Entity Catalog --
    lines.append("## Entity Catalog")
    lines.append("")

    for et in EntityType:
        entities = kg.entities_of_type(et)
        if not entities:
            continue

        label = et.value.replace("_", " ").title()
        lines.append(f"### {label}s ({len(entities)})")
        lines.append("")
        lines.append("| Name | Confidence | Method | Source Section |")
        lines.append("|------|-----------|--------|----------------|")
        for e in entities:
            conf_icon = "HIGH" if e.confidence >= 0.8 else ("MED" if e.confidence >= 0.5 else "LOW")
            lines.append(
                f"| {e.name} | {conf_icon} {e.confidence:.0%} "
                f"| {e.extraction_method} | {e.source_section or '—'} |"
            )
        lines.append("")

    # -- Relation Map --
    if kg.relations:
        lines.append("## Relationship Map")
        lines.append("")
        lines.append("| Source | Relation | Target | Confidence |")
        lines.append("|--------|----------|--------|-----------|")
        for r in kg.relations:
            src = kg.get_entity(r.source_id)
            tgt = kg.get_entity(r.target_id)
            src_name = src.name if src else r.source_id
            tgt_name = tgt.name if tgt else r.target_id
            lines.append(
                f"| {src_name} | {r.relation_type.value.replace('_', ' ')} "
                f"| {tgt_name} | {r.confidence:.0%} |"
            )
        lines.append("")

    # -- Architecture Diagram --
    lines.append("## Auto-Generated Architecture Diagram")
    lines.append("")
    lines.append("```mermaid")
    lines.append(kg.to_mermaid())
    lines.append("```")
    lines.append("")

    # -- Document Structure --
    lines.append("## Document Structure")
    lines.append("")
    lines.append(f"- **Sections:** {len(doc.sections)}")
    lines.append(f"- **Content Blocks:** {len(doc.all_blocks)}")
    lines.append(f"- **Mermaid Diagrams:** {len(doc.mermaid_diagrams)}")
    lines.append(f"- **Source Length:** {len(doc.raw_markdown):,} characters")
    lines.append("")

    # Section tree
    lines.append("### Section Outline")
    lines.append("")
    for sec in doc.sections:
        _render_section_tree(lines, sec, indent=0)
    lines.append("")

    lines.append("---")
    lines.append(f"*Report generated by opendocs v0.1 • {now}*")
    lines.append("")

    return "\n".join(lines)


def _render_section_tree(lines: list[str], section, indent: int = 0) -> None:
    """Recursively render the section tree as a Markdown list."""
    prefix = "  " * indent
    block_count = len(section.blocks)
    lines.append(f"{prefix}- **{section.title}** ({block_count} blocks)")
    for sub in section.subsections:
        _render_section_tree(lines, sub, indent + 1)
