"""
Pacote ZIP completo da RSL ativa: protocolo, dados, síntese, LaTeX (article + ABNT) e rastreabilidade.
"""

from __future__ import annotations

import json
import zipfile
from io import BytesIO, StringIO

from rsl.services.export_latex import (
    MARKER_VERSION,
    RSL_SYSTEM_NAME,
    build_bibtex_file,
    build_synthesis_latex,
)
from rsl.services.exports import (
    export_articles_xlsx,
    export_extraction_matrix_csv,
    export_extraction_xlsx,
    export_protocol_docx,
    export_synthesis_docx,
    export_synthesis_xlsx,
)
from rsl.services.export_presentation import export_synthesis_presentation_html
from rsl.services.export_upe import export_upe_thesis_zip
from rsl.services.synthesis import package_to_json


def _readme_text(review, package: dict) -> str:
    meta = package["meta"]
    funnel = package["funnel"]
    return f"""# Pacote completo da RSL — {review.title}

Revisão ID: {review.id} | Slug: {review.slug}
Gerado em: {meta.get('generated_at')} UTC
Formato de marcadores: {MARKER_VERSION}

## Conteúdo

- `01-protocolo/` — protocolo da revisão (DOCX)
- `02-dados/` — artigos, extração, tabelas agregadas, matriz CSV completa
- `03-sintese/` — relatório discursivo DOCX e discussão em Markdown
- `04-latex/` — LaTeX article, ABNT (abntex2), BibTeX e instruções de compilação
- `05-modelo-upe/` — modelo UPE com `conteudo/rsl.tex` preenchido (se o ZIP do modelo existir)
- `rastreabilidade.json` — metadados e contagens auditáveis (sem texto longo)
- `MARCADORES-RSL.md` — documentação dos marcadores % RSL:…

## Seleção e funil

- Identificados: {funnel['identificados']}
- Aceitos: {funnel['aceitos']}
- Seleção final (síntese): {funnel['selecao_final']}

## Compilação LaTeX (ABNT)

1. Instale TeX Live com abntex2.
2. `cd 04-latex`
3. `pdflatex sintese-rsl-abntex2.tex`
4. `bibtex sintese-rsl-abntex2`
5. `pdflatex sintese-rsl-abntex2.tex` (duas vezes)

Alternativa sem ABNT: compile `sintese-rsl.tex` (classe article, referências embutidas).

Todos os números das tabelas derivam da extração estruturada da RSL ativa no {RSL_SYSTEM_NAME}.
"""


def _markers_doc() -> str:
    return """# Marcadores RSL (LaTeX)

| Marcador | Uso |
|----------|-----|
| `% RSL-SYNTHESIS-V1` | Versão do export |
| `% RSL:BLOCK:<nome>:BEGIN/END` | Bloco lógico (METADATA, PROTOCOL, …) |
| `% RSL:SECTION:<chave>:BEGIN/END` | Seção narrativa |
| `% RSL:TABLE:<id>:BEGIN/END` | Tabela auditável |
| `% RSL:DATA:<chave>=<valor>` | Metadado escalar |
| `% RSL:BIB:<article_id>` | Referência bibliográfica |
| `% RSL:STUDY:<id>:BEGIN/END` | Evidência primária no apêndice |

Ferramentas podem parsear o `.tex` por regex nos comentários sem executar LaTeX.
"""


def _discussion_markdown(package: dict) -> str:
    lines = ["# Discussão da RSL (rascunho exportado)\n"]
    for key, title in [
        ("resumo_executivo", "Resumo executivo"),
        ("conformidade_prisma", "Conformidade PRISMA"),
        ("introducao", "Introdução"),
        ("metodos", "Metodologia"),
        ("resultados_selecao", "Resultados da seleção"),
        ("caracterizacao", "Caracterização"),
        ("sintese_tematica", "Síntese temática"),
        ("lacunas_literatura", "Lacunas da literatura"),
        ("discussao", "Discussão"),
        ("lacunas_rsl", "Limitações da revisão"),
        ("qualidade_metodologica_rsl", "Qualidade metodológica da RSL"),
        ("conclusao", "Conclusão"),
    ]:
        text = package.get("sections", {}).get(key, "")
        lines.append(f"\n## {title}\n\n{text}\n")
    return "\n".join(lines)


def _compile_instructions() -> str:
    return f"""Compilação LaTeX — RSL {RSL_SYSTEM_NAME}
================================

OPÇÃO A — article (sintese-rsl.tex)
  pdflatex sintese-rsl.tex
  (referências já em \\begin{{thebibliography}})

OPÇÃO B — ABNT (sintese-rsl-abntex2.tex + rsl-referencias.bib)
  pdflatex sintese-rsl-abntex2.tex
  bibtex sintese-rsl-abntex2
  pdflatex sintese-rsl-abntex2.tex
  pdflatex sintese-rsl-abntex2.tex

Requisitos ABNT: abntex2 instalado (TeX Live completo ou pacote abntex2).
"""


def export_complete_review_bundle(review, package: dict) -> BytesIO:
    """ZIP com todos os artefatos da revisão sistemática ativa."""
    slug = review.slug or f"review-{review.id}"
    root = f"{slug}-rsl-completo"

    buf = BytesIO()
    with zipfile.ZipFile(buf, "w", zipfile.ZIP_DEFLATED) as zf:
        def add_bytes(path: str, data: bytes):
            zf.writestr(f"{root}/{path}", data)

        def add_text(path: str, text: str):
            zf.writestr(f"{root}/{path}", text.encode("utf-8"))

        add_text("README.md", _readme_text(review, package))
        add_text("MARCADORES-RSL.md", _markers_doc())

        trace = json.loads(package_to_json(package))
        trace["sections_keys"] = list(package.get("sections", {}).keys())
        add_text("rastreabilidade.json", json.dumps(trace, ensure_ascii=False, indent=2))

        add_bytes("01-protocolo/protocolo.docx", export_protocol_docx(review).read())
        add_bytes("02-dados/artigos-importados.xlsx", export_articles_xlsx(review).read())
        add_bytes("02-dados/extracao-selecao-final.xlsx", export_extraction_xlsx(review).read())
        add_bytes("02-dados/sintese-tabelas.xlsx", export_synthesis_xlsx(review, package).read())
        add_bytes(
            "02-dados/matriz-extracao-completa.csv",
            export_extraction_matrix_csv(review, package).read(),
        )

        add_bytes("03-sintese/sintese-rsl.docx", export_synthesis_docx(review, package).read())
        add_bytes(
            "03-sintese/apresentacao-rsl.html",
            export_synthesis_presentation_html(review, package).read(),
        )
        add_text("03-sintese/discussao.md", _discussion_markdown(package))

        add_text("04-latex/sintese-rsl.tex", build_synthesis_latex(review, package, style="article"))
        add_text(
            "04-latex/sintese-rsl-abntex2.tex",
            build_synthesis_latex(review, package, style="abntex2"),
        )
        add_text("04-latex/rsl-referencias.bib", build_bibtex_file(package))
        add_text("04-latex/COMO-COMPILAR.txt", _compile_instructions())

        try:
            upe_zip = export_upe_thesis_zip(review, package)
            with zipfile.ZipFile(upe_zip, "r") as upe_inner:
                for name in upe_inner.namelist():
                    zf.writestr(f"{root}/05-modelo-upe/{name}", upe_inner.read(name))
        except FileNotFoundError:
            add_text(
                "05-modelo-upe/LEIA-ME.txt",
                f"Modelo LATEX_TESE_DOUTORADO_2024.zip não encontrado na raiz do {RSL_SYSTEM_NAME}.\n"
                "Use o botão «Modelo UPE (Overleaf)» na síntese quando o ZIP estiver disponível.\n",
            )

    buf.seek(0)
    return buf
