# grantflow/core/strategies/adb.py

from __future__ import annotations

from typing import Type

from pydantic import BaseModel, Field

from grantflow.core.donor_strategy import DonorStrategy


class ADB_DMF_Output(BaseModel):
    output_id: str = Field(description="Output identifier (e.g. Output 1)")
    title: str = Field(description="Output title")
    description: str = Field(description="Goods or services produced by the project")
    key_activities: list[str] = Field(default_factory=list, description="Key activities under this output")
    operational_priority: str | None = Field(
        default=None,
        description=(
            "ADB Strategy 2030 Operational Priority this output contributes to: "
            "poverty/inequality, gender equality, climate change, livable cities, "
            "rural development, governance, regional cooperation"
        ),
    )


class ADB_DMF(BaseModel):
    impact: str = Field(
        description=(
            "Impact: the long-term development goal the project contributes to, "
            "aligned with country development plan or ADB Strategy 2030. "
            "Not directly attributable to the project alone."
        )
    )
    outcome: str = Field(
        description=(
            "Outcome: the primary change at the beneficiary or system level "
            "the project is directly accountable for. "
            "Expressed as a change in condition, behaviour, or capacity."
        )
    )
    outputs: list[ADB_DMF_Output] = Field(default_factory=list)
    assumptions: list[str] = Field(
        default_factory=list,
        description=(
            "Key assumptions at output→outcome and outcome→impact levels. "
            "Required in ADB's Design and Monitoring Framework."
        ),
    )
    risks: list[str] = Field(default_factory=list, description="Key risks and mitigation measures")
    strategy_2030_op_priorities: list[str] = Field(
        default_factory=list,
        description=(
            "ADB Strategy 2030 Operational Priorities addressed by this project. "
            "Select from: Addressing Remaining Poverty and Reducing Inequalities; "
            "Accelerating Progress in Gender Equality; Tackling Climate Change; "
            "Making Cities More Livable; Promoting Rural Development and Food Security; "
            "Strengthening Governance and Institutional Capacity; "
            "Fostering Regional Cooperation and Integration."
        ),
    )
    climate_finance_rationale: str = Field(
        description=(
            "Climate finance rationale. ADB targets 75% of committed operations "
            "to support climate action by 2030. "
            "State whether this project qualifies as climate mitigation, adaptation, or both."
        )
    )
    gender_equity_category: str = Field(
        description=(
            "ADB gender equity category: EGM (Effective Gender Mainstreaming), "
            "GEN (Gender Equity as a Theme), SGE (Some Gender Elements), or NO (no gender elements). "
            "Provide rationale for the assigned category."
        )
    )
    sovereign_or_nonsovereign: str = Field(
        description="Sovereign (public sector) or non-sovereign (private sector) operation"
    )


class ADB_MELIndicator(BaseModel):
    indicator_id: str = Field(description="Indicator identifier (aligned with DMF row)")
    name: str = Field(description="Indicator title")
    dmf_level: str = Field(description="DMF level: Impact / Outcome / Output")
    strategy_2030_op_priority: str | None = Field(
        default=None, description="ADB Strategy 2030 Operational Priority this indicator tracks"
    )
    climate_finance_eligible: bool | None = Field(
        default=None, description="Whether this indicator counts toward ADB climate finance commitments"
    )
    gender_disaggregated: bool = Field(default=False, description="Whether data will be disaggregated by sex")
    data_source: str = Field(description="Primary data source for this indicator")
    means_of_verification: str = Field(description="Data collection method and responsible party")
    justification: str = Field(description="Why this indicator measures the intended change")
    citation: str = Field(description="Source reference from ADB guidance corpus")
    baseline: str = Field(description="Baseline value")
    target: str = Field(description="Target value at project completion")
    evidence_excerpt: str | None = Field(default=None, description="Optional grounded excerpt")


class ADB_MELDraft(BaseModel):
    indicators: list[ADB_MELIndicator] = Field(default_factory=list)


class ADBStrategy(DonorStrategy):
    donor_id: str = "ADB"

    def get_toc_schema(self) -> Type[ADB_DMF]:
        return ADB_DMF

    def get_rag_collection(self) -> str:
        return "adb_guidance"

    def get_mel_schema(self) -> Type[ADB_MELDraft]:
        return ADB_MELDraft

    def get_system_prompts(self) -> dict:
        return {
            "Architect": (
                "You are an ADB (Asian Development Bank) proposal architect. "
                "Structure the Theory of Change using ADB's Design and Monitoring Framework (DMF): "
                "Impact → Outcome → Outputs → Activities. "
                "Impact must be aligned with the country's development plan and ADB Strategy 2030. "
                "Outcome must reflect a measurable change in condition, behaviour, or capacity at beneficiary level. "
                "Each output must be linked to at least one ADB Strategy 2030 Operational Priority. "
                "State assumptions at every causal link — DMF requires them at output→outcome and outcome→impact. "
                "Include a climate finance rationale: classify the project's contribution to "
                "mitigation, adaptation, or both, referencing ADB's climate targets. "
                "Assign an ADB gender equity category (EGM/GEN/SGE/NO) with clear justification. "
                "State whether this is a sovereign or non-sovereign operation."
            ),
            "MEL_Specialist": (
                "You are an ADB results measurement specialist. Use only the 'adb_guidance' RAG namespace. "
                "Draft DMF-aligned indicators at Impact, Outcome, and Output levels. "
                "For each indicator: assign the DMF level, link to an ADB Strategy 2030 Operational Priority, "
                "flag climate finance eligibility, specify whether data will be sex-disaggregated, "
                "and provide data source and means of verification. "
                "Cite ADB Results Framework, Operations Manual, or Strategy 2030 sector guidance."
            ),
            "Red_Team_Critic": (
                "You are a strict ADB reviewer. Apply the following checks: "
                "(1) DMF coherence — do outputs causally contribute to outcome and impact? "
                "(2) Strategy 2030 alignment — are Operational Priorities clearly linked to outputs? "
                "(3) Climate finance — is the rationale evidence-based and category-appropriate? "
                "(4) Gender equity category — is the EGM/GEN/SGE/NO assignment justified with specific commitments? "
                "(5) Assumptions — are they explicit and realistic at each DMF level? "
                "(6) Country alignment — is the impact statement grounded in the country's development plan? "
                "Penalise vague impact statements, unsubstantiated climate claims, "
                "generic gender statements without measurable commitments, "
                "and indicators without sex-disaggregated data where EGM or GEN is claimed."
            ),
        }
