from __future__ import annotations

from grantflow.core.strategies.factory import DonorFactory
from grantflow.swarm.nodes import architect_generation as architect_generation_module
from grantflow.swarm.nodes.architect_generation import _fallback_structured_toc


def test_fallback_structured_toc_uses_giz_specific_programme_phrasing():
    payload, _engine = _fallback_structured_toc(
        DonorFactory.get_strategy("giz").get_toc_schema(),
        donor_id="giz",
        project="SME Resilience and Youth Employment Skills Acceleration",
        country="Jordan",
        revision_hint="",
        evidence_hits=[],
    )

    programme_objective = str(payload.get("programme_objective") or "")
    assert "adaptive implementation" in programme_objective.lower()
    assert "delivery" in programme_objective.lower()
    assert "sustainability outcomes" in programme_objective.lower()
    outcomes = payload.get("outcomes") or []
    assert outcomes
    assert "delivery partners implement stronger" in str(outcomes[0].get("title") or "").lower()
    assert "adaptive implementation" in str(outcomes[0].get("description") or "").lower()
    sustainability = payload.get("sustainability_factors") or []
    assert sustainability
    assert "partner institutions continue financing" in str(sustainability[0]).lower()


def test_fallback_structured_toc_uses_un_agencies_specific_programme_phrasing():
    payload, _engine = _fallback_structured_toc(
        DonorFactory.get_strategy("un_agencies").get_toc_schema(),
        donor_id="un_agencies",
        project="Inclusive Education Recovery",
        country="Nepal",
        revision_hint="",
        evidence_hits=[],
    )

    project_goal = str(payload.get("project_goal") or "")
    assert "inclusive education recovery outcomes in nepal" in project_goal.lower()
    objectives = payload.get("objectives") or payload.get("development_objectives") or []
    assert objectives
    assert (
        "schools and local education authorities deliver more reliable inclusive education recovery"
        in str(objectives[0].get("title") or "").lower()
    )
    assert "field-verified inclusive education recovery delivery" in str(objectives[0].get("description") or "").lower()
    assumptions = payload.get("assumptions") or payload.get("critical_assumptions") or []
    assert assumptions
    assert (
        "local education authorities, schools, and community stakeholders continue supporting equitable inclusive education recovery delivery"
        in str(assumptions[0]).lower()
    )


def test_fallback_structured_toc_uses_eu_and_worldbank_more_reviewer_useful_phrasing():
    eu_payload, _ = _fallback_structured_toc(
        DonorFactory.get_strategy("eu").get_toc_schema(),
        donor_id="eu",
        project="Digital Governance",
        country="Moldova",
        revision_hint="",
        evidence_hits=[],
    )
    wb_payload, _ = _fallback_structured_toc(
        DonorFactory.get_strategy("worldbank").get_toc_schema(),
        donor_id="worldbank",
        project="Public Sector Performance",
        country="Uzbekistan",
        revision_hint="",
        evidence_hits=[],
    )

    eu_outcomes = eu_payload.get("expected_outcomes") or []
    assert eu_outcomes
    assert (
        "residents and businesses experience faster, more accountable digital governance services"
        in str(eu_outcomes[-1].get("title") or "").lower()
    )

    wb_results = wb_payload.get("results_chain") or []
    assert wb_results
    assert "service standards and supervision routines" in str(wb_results[0].get("title") or "").lower()
    assert "response-time and quality targets" in str(wb_results[-1].get("title") or "").lower()


def test_architect_un_agencies_evidence_signal_and_review_hint_are_programme_shaped():
    signal = architect_generation_module._architect_evidence_signal(
        donor_id="un_agencies",
        excerpt="Cluster review and field monitoring evidence",
        source="un_agencies_guidance",
    )
    hint = architect_generation_module._architect_review_hint(
        donor_id="un_agencies",
        result_level="outcome",
        evidence_signal=signal,
    )

    assert signal == "inter-agency review evidence"
    assert "un programme and sector-review package" in hint.lower()


def test_fallback_structured_toc_uses_state_department_specific_program_logic_phrasing():
    payload, _engine = _fallback_structured_toc(
        DonorFactory.get_strategy("state_department").get_toc_schema(),
        donor_id="state_department",
        project="Independent Media Resilience",
        country="Georgia",
        revision_hint="",
        evidence_hits=[],
    )

    strategic_context = str(payload.get("strategic_context") or "")
    assert "information-space" in strategic_context.lower()
    assert "partner safeguarding" in strategic_context.lower()
    assert str(payload.get("program_goal") or "").lower() == "improve independent media resilience outcomes in georgia."
    objectives = payload.get("objectives") or []
    assert objectives
    assert "political and operational pressure" in str(objectives[0].get("objective") or "").lower()
    assert "democracy, human rights, and governance" in str(objectives[0].get("line_of_effort") or "").lower()
    assert "safeguarding" in str(objectives[0].get("expected_change") or "").lower()
    stakeholders = payload.get("stakeholder_map") or []
    assert stakeholders
    assert "information-integrity feedback" in str(stakeholders[-1]).lower()
    risks = payload.get("risk_mitigation") or []
    assert risks
    assert "contingency planning" in str(risks[0]).lower()
    assert "information-integrity" in str(risks[-1]).lower()


def test_fallback_structured_toc_uses_eu_specific_intervention_logic_phrasing():
    strategy = DonorFactory.get_strategy("eu")
    payload, engine = _fallback_structured_toc(
        strategy.get_toc_schema(),
        donor_id="eu",
        project="Digital Governance",
        country="Moldova",
        revision_hint="",
        evidence_hits=[],
    )

    assert engine == "contract_synthesizer"
    assert "digital governance" in payload["overall_objective"]["title"].lower()
    assert "eu intervention logic" in payload["overall_objective"]["rationale"].lower()
    assert payload["specific_objectives"]
    assert any("institutional capacity" in row["title"].lower() for row in payload["specific_objectives"])
    assert payload["expected_outcomes"]
    assert any("measurable improvements" in row["expected_change"].lower() for row in payload["expected_outcomes"])
    assert payload["safeguarding_annex"]
    assert len([row for row in payload["safeguarding_annex"] if str(row).strip()]) >= 1


def test_fallback_structured_toc_uses_worldbank_specific_results_chain_phrasing():
    strategy = DonorFactory.get_strategy("worldbank")
    payload, engine = _fallback_structured_toc(
        strategy.get_toc_schema(),
        donor_id="worldbank",
        project="Public Sector Performance",
        country="Uzbekistan",
        revision_hint="",
        evidence_hits=[],
    )

    assert engine == "contract_synthesizer"
    assert (
        payload["project_development_objective"].lower()
        == "improve public sector performance and service delivery in uzbekistan."
    )
    assert payload["objectives"]
    assert any("agency performance and accountability" in row["title"].lower() for row in payload["objectives"])
    assert payload["results_chain"]
    assert any(
        "participating agencies implement workflow" in row["description"].lower() for row in payload["results_chain"]
    )
    assert any("processing time" in row["indicator_focus"].lower() for row in payload["results_chain"])


def test_fallback_structured_toc_uses_usaid_specific_compact_objective_phrasing():
    strategy = DonorFactory.get_strategy("usaid")
    payload, engine = _fallback_structured_toc(
        strategy.get_toc_schema(),
        donor_id="usaid",
        project="Responsible AI Skills for Civil Service Modernization",
        country="Kazakhstan",
        revision_hint="",
        evidence_hits=[],
    )

    assert engine == "contract_synthesizer"
    assert (
        payload["project_goal"]
        == "Improve responsible ai skills for civil service modernization outcomes in Kazakhstan."
    )
    assert payload["development_objectives"]
    assert any("civil servants" in row["description"].lower() for row in payload["development_objectives"])
    assert payload["critical_assumptions"]
    assert any("public institutions" in row.lower() for row in payload["critical_assumptions"])


def test_fallback_structured_toc_does_not_leak_noisy_evidence_hint_into_generic_descriptions():
    strategy = DonorFactory.get_strategy("usaid")
    payload, _engine = _fallback_structured_toc(
        strategy.get_toc_schema(),
        donor_id="usaid",
        project="Responsible AI Skills for Civil Service Modernization",
        country="Kazakhstan",
        revision_hint="",
        evidence_hits=[
            {
                "excerpt": (
                    "Evidence hint: present. Grounding gate warning: architect_retrieval_no_hits. "
                    "Replace repeated boilerplate in the next revision."
                )
            }
        ],
    )

    all_text = " ".join(
        [
            payload["project_goal"],
            *(row["description"] for row in payload["development_objectives"]),
            *(row for row in payload["critical_assumptions"]),
        ]
    ).lower()
    assert "evidence hint" not in all_text
    assert "architect_retrieval_no_hits" not in all_text
    assert "replace repeated boilerplate" not in all_text
