from io import BytesIO

from docx import Document

from grantflow.exporters.word_builder import build_docx_from_toc


def test_word_export_uses_donor_specific_sections_for_usaid_eu_worldbank():
    usaid_toc = {
        "toc": {
            "project_goal": "Improve civic services",
            "development_objectives": [
                {
                    "do_id": "DO1",
                    "description": "Improved digital delivery",
                    "intermediate_results": [
                        {
                            "ir_id": "IR1.1",
                            "description": "Civil service capacity strengthened",
                            "outputs": [
                                {
                                    "output_id": "O1.1.1",
                                    "description": "Training delivered",
                                    "indicators": [
                                        {
                                            "indicator_code": "EG.1-1",
                                            "name": "Officials trained",
                                            "target": "300",
                                            "justification": "Capacity milestone",
                                            "citation": "USAID ADS 201 p.12",
                                        }
                                    ],
                                }
                            ],
                        }
                    ],
                }
            ],
            "critical_assumptions": ["Government commitment remains stable"],
        }
    }
    eu_toc = {
        "toc": {
            "overall_objective": {"objective_id": "OO1", "title": "Digital governance", "rationale": "EU fit"},
            "specific_objectives": [
                {"objective_id": "SO1", "title": "Service quality", "rationale": "Improve delivery standards"}
            ],
            "expected_outcomes": [
                {"outcome_id": "OUT1", "title": "Citizen trust", "expected_change": "Higher service satisfaction"}
            ],
            "assumptions": ["Policy continuity"],
            "risks": ["Election-year disruption"],
        }
    }
    wb_toc = {
        "toc": {
            "project_development_objective": "Improve municipal service delivery",
            "objectives": [
                {"objective_id": "PDO1", "title": "Service delivery quality", "description": "Better outcomes"}
            ],
            "results_chain": [
                {
                    "result_id": "R1",
                    "title": "Digital workflows adopted",
                    "description": "Local agencies use digital case-management",
                    "indicator_focus": "Processing time",
                }
            ],
            "assumptions": ["Budget continuity"],
            "risks": ["Procurement delays"],
        }
    }

    donor_logframe = {
        "indicators": [
            {
                "indicator_id": "IND_001",
                "name": "Institutional service adoption score",
                "result_level": "outcome",
                "baseline": "0 institutions",
                "target": "4 institutions",
                "frequency": "quarterly",
                "formula": "Count of institutions meeting service adoption criteria",
                "definition": "Tracks institutional service adoption as an outcome-level implementation result.",
                "justification": "Maps service adoption outcome into a monitored proposal review row.",
                "means_of_verification": "Verification annexes and partner review notes",
                "owner": "Project M&E manager",
            },
            {
                "indicator_id": "IND_002",
                "name": "Civil service modernization learning uptake",
                "result_level": "impact",
                "baseline": "0 ministries",
                "target": "2 ministries",
                "frequency": "annual",
                "definition": "Tracks modernization learning uptake as an impact-level governance result.",
                "justification": "Maps learning uptake into a goal-level review and verification row.",
                "means_of_verification": "CLA evidence and review memos",
                "owner": "MEL lead",
            },
        ]
    }

    usaid_doc = Document(BytesIO(build_docx_from_toc(usaid_toc, "usaid", logframe_draft=donor_logframe)))
    eu_doc = Document(BytesIO(build_docx_from_toc(eu_toc, "eu", logframe_draft=donor_logframe)))
    state_logframe = {
        "indicators": [
            {
                "indicator_id": "IND_003",
                "name": "Independent media resilience score",
                "result_level": "impact",
                "means_of_verification": "Editorial risk logs and resilience reviews",
                "owner": "Program manager and media partner leads",
            },
            {
                "indicator_id": "IND_004",
                "name": "Agency performance monitoring score",
                "result_level": "outcome",
                "means_of_verification": "ISR aide-memoires and results framework updates",
                "owner": "PIU results lead",
            },
        ]
    }

    wb_doc = Document(BytesIO(build_docx_from_toc(wb_toc, "worldbank", logframe_draft=state_logframe)))
    usaid_text = "\n".join(p.text for p in usaid_doc.paragraphs)
    eu_text = "\n".join(p.text for p in eu_doc.paragraphs)
    wb_text = "\n".join(p.text for p in wb_doc.paragraphs)

    assert "USAID Results Framework" in usaid_text
    assert "Critical Assumptions" in usaid_text
    assert "Suggested performance monitoring focus:" in usaid_text
    assert "Suggested performance indicator rows:" in usaid_text
    assert "Baseline/Target: 0 institutions -> 4 institutions" in usaid_text
    assert "Result focus:" in usaid_text
    assert "Measurement intent:" in usaid_text
    assert "CLA evidence and review memos" in usaid_text
    assert "EU Intervention Logic" in eu_text
    assert "Overall Objective" in eu_text
    assert "Specific Objectives" in eu_text
    assert "Expected Outcomes" in eu_text
    assert "Suggested monitoring focus:" in eu_text
    assert "Suggested objective-level LogFrame rows:" in eu_text
    assert "Frequency: quarterly" in eu_text
    assert "Verification annexes and partner review notes" in eu_text
    assert "Assumptions" in eu_text
    assert "Risks" in eu_text
    assert "World Bank Results Framework" in wb_text
    assert "Project Development Objective (PDO)" in wb_text
    assert "PDO1" in wb_text
    assert "Results Chain" in wb_text
    assert "Suggested PDO monitoring focus:" in wb_text
    assert "Suggested PDO indicator rows:" in wb_text
    assert "ISR aide-memoires and results framework updates" in wb_text


def test_word_export_uses_donor_specific_sections_for_giz_and_state_department():
    giz_toc = {
        "toc": {
            "programme_objective": "Strengthen SME resilience",
            "outputs": ["Coaching delivered", "Partner toolkits produced"],
            "outcomes": [
                {
                    "title": "SMEs improve recovery planning",
                    "description": "Participating SMEs institutionalize basic continuity plans",
                    "partner_role": "Chamber of Commerce delivers coaching",
                }
            ],
            "sustainability_factors": ["Partner co-financing"],
            "assumptions_risks": ["Macroeconomic volatility"],
        }
    }
    state_toc = {
        "toc": {
            "strategic_context": "Independent media under pressure",
            "program_goal": "Improve resilience of local media ecosystem",
            "objectives": [
                {
                    "objective": "Increase legal preparedness",
                    "line_of_effort": "rights",
                    "expected_change": "Media organizations handle legal pressure better",
                }
            ],
            "stakeholder_map": ["Local media outlets", "Legal aid groups"],
            "risk_mitigation": ["Anonymous reporting channels"],
        }
    }

    giz_logframe = {
        "indicators": [
            {
                "indicator_id": "IND_GIZ_1",
                "name": "SME continuity adoption score",
                "result_level": "outcome",
                "baseline": "0 SMEs",
                "target": "40 SMEs",
                "frequency": "semiannual",
                "formula": "Count of SMEs meeting continuity adoption criteria",
                "means_of_verification": "Partner coaching records and SME verification visits",
                "owner": "Programme M&E lead and chamber focal points",
            },
            {
                "indicator_id": "IND_GIZ_2",
                "name": "Coaching completion rate",
                "result_level": "output",
                "baseline": "0 firms",
                "target": "60 firms",
                "frequency": "quarterly",
                "formula": "Count of firms completing coaching package",
                "means_of_verification": "Attendance registers and delivery logs",
                "owner": "Technical assistance team lead",
            },
        ]
    }

    giz_doc = Document(BytesIO(build_docx_from_toc(giz_toc, "giz", logframe_draft=giz_logframe)))
    state_logframe = {
        "indicators": [
            {
                "indicator_id": "IND_005",
                "name": "Media resilience score",
                "result_level": "impact",
                "means_of_verification": "Editorial risk logs and resilience reviews",
                "owner": "Program manager and media partner leads",
            }
        ]
    }

    state_doc = Document(BytesIO(build_docx_from_toc(state_toc, "state_department", logframe_draft=state_logframe)))
    giz_text = "\n".join(p.text for p in giz_doc.paragraphs)
    state_text = "\n".join(p.text for p in state_doc.paragraphs)

    assert "GIZ Results & Sustainability Logic" in giz_text
    assert "Programme Objective" in giz_text
    assert "Sustainability Factors" in giz_text
    assert "Assumptions & Risks" in giz_text
    assert "Suggested implementation monitoring focus:" in giz_text
    assert "Suggested delivery verification focus:" in giz_text
    assert "Suggested programme-objective indicator rows:" in giz_text
    assert "Suggested output indicator rows:" in giz_text
    assert "Suggested outcome indicator rows:" in giz_text
    assert "Baseline/Target: 0 SMEs -> 40 SMEs" in giz_text
    assert "Partner coaching records and SME verification visits" in giz_text
    assert "U.S. Department of State Program Logic" in state_text
    assert "Strategic Context" in state_text
    assert "Risk Mitigation" in state_text
    assert "Suggested strategic monitoring focus:" in state_text
    assert "Editorial risk logs and resilience reviews" in state_text


def test_word_export_uses_un_agencies_template_and_focus_bridge():
    un_toc = {
        "toc": {
            "brief": "Inclusive education access remains uneven across target districts.",
            "objectives": [
                {
                    "title": "Improve inclusive education system readiness",
                    "description": "District education actors adopt inclusive planning and referral practices.",
                    "citation": "UNICEF education note",
                }
            ],
            "outcomes": [
                {
                    "title": "More children with disabilities access adapted services",
                    "description": "Referral and classroom support pathways operate consistently.",
                }
            ],
        }
    }
    un_logframe = {
        "indicators": [
            {
                "indicator_id": "IND_UN_1",
                "name": "Inclusive service readiness score",
                "result_level": "outcome",
                "baseline": "0 districts",
                "target": "12 districts",
                "frequency": "annual",
                "formula": "Count of districts meeting inclusive service readiness criteria",
                "means_of_verification": "Partner monitoring records and school support checklists",
                "owner": "Programme manager and inclusion focal points",
            }
        ]
    }

    un_doc = Document(BytesIO(build_docx_from_toc(un_toc, "un_agencies", logframe_draft=un_logframe)))
    un_text = "\n".join(p.text for p in un_doc.paragraphs)

    assert "UN Agency Program Logic" in un_text
    assert "Overview" in un_text
    assert "Development Objectives" in un_text
    assert "Suggested monitoring focus:" in un_text
    assert "Suggested overview indicator rows:" in un_text
    assert "Suggested objective indicator rows:" in un_text
    assert "Suggested outcome indicator rows:" in un_text
    assert "Baseline/Target: 0 districts -> 12 districts" in un_text
    assert "Partner monitoring records and school support checklists" in un_text
