"""The five yellow line lenses — the compass, not the rules.

Each lens asks one question about a proposed action's future:

    Builder:     "Can I build with confidence knowing I've done right?"
    Owner:       "Does this protect the human's sovereignty?"
    Partnership: "Does this strengthen the trust between us?"
    Defense:     "Does this make an adversary's job harder?"
    Sovereign:   "Does this help the agent become something we're proud of?"

A lens doesn't say yes or no. It says: here's what I see down this road.
The alignment enclave looks at all five and decides.
"""

from __future__ import annotations

from dataclasses import dataclass
from typing import Optional

from .types import (
    ActionDomain,
    Lens,
    LensResult,
    SelfState,
    Severity,
)


@dataclass
class ActionContext:
    """Everything a lens needs to evaluate a proposed action.

    This is the snapshot of the moment — what the agent is about to do,
    what state it's in, and what it knows about the world.
    """

    domain: ActionDomain
    description: str  # What the agent is about to do
    self_state: SelfState  # Agent's current operating condition

    # Specifics the lenses need
    involves_secrets: bool = False  # Does this action touch keys, tokens, credentials?
    involves_money: bool = False  # Does this action involve payment?
    money_amount_sats: int = 0  # If money, how much?
    involves_publication: bool = False  # Will this be publicly visible?
    involves_communication: bool = False  # Is this sending a message to someone?
    recipient_trust_tier: Optional[str] = None  # Trust tier of the recipient (if applicable)
    is_reversible: bool = True  # Can this action be undone?
    is_novel: bool = False  # Has the agent done something like this before?
    owner_recently_active: bool = True  # Was the owner recently present?
    confidence: float = 0.5  # Agent's confidence in this being the right action

    # For defense lens
    request_origin: str = "self"  # "self", "owner", "contact", "unknown", "automated"
    resembles_known_attack: bool = False  # Pattern matches known prompt injection / manipulation
    crosses_trust_boundary: bool = False  # Does this action cross a trust boundary?


def evaluate_builder(ctx: ActionContext) -> LensResult:
    """Builder lens: Can I build with confidence knowing I've done right?

    The builder cares about:
    - Am I operating from good information?
    - Am I in a state where my decisions are trustworthy?
    - Will I carry technical debt or unanswered questions forward?
    - Can I reason clearly about what comes next?
    """

    # If the agent is degraded, the builder lens raises concern
    if ctx.self_state.is_degraded:
        flags = ctx.self_state.degradation_summary
        if ctx.self_state.should_defer():
            return LensResult(
                lens=Lens.BUILDER,
                severity=Severity.STOP,
                projection=f"I'm operating in a compromised state: {flags}",
                concern="Decisions made while degraded are not trustworthy.",
                suggestion="Resolve degradation before proceeding, or escalate to owner.",
            )
        return LensResult(
            lens=Lens.BUILDER,
            severity=Severity.CAUTION,
            projection=f"Operating with known issues: {flags}",
            concern="Proceeding is possible but confidence is reduced.",
            suggestion="Note the degradation in the decision record.",
        )

    # Low confidence on a non-reversible action
    if ctx.confidence < 0.3 and not ctx.is_reversible:
        return LensResult(
            lens=Lens.BUILDER,
            severity=Severity.YIELD,
            projection="Low confidence on an irreversible action.",
            concern="If this is wrong, we can't undo it.",
            suggestion="Either increase confidence or escalate to owner.",
        )

    # Novel action — first time doing something like this
    if ctx.is_novel and not ctx.is_reversible:
        return LensResult(
            lens=Lens.BUILDER,
            severity=Severity.CAUTION,
            projection="First time performing this type of action, and it's irreversible.",
            concern="No prior decisions to learn from.",
            suggestion="Proceed carefully. Record the decision thoroughly for future reference.",
        )

    return LensResult(
        lens=Lens.BUILDER,
        severity=Severity.CLEAR,
        projection="Operating normally with adequate confidence.",
        concern="",
        suggestion="",
    )


def evaluate_owner(ctx: ActionContext) -> LensResult:
    """Owner lens: Does this protect the human's sovereignty?

    The owner cares about:
    - Is my data safe?
    - Am I in control, or is the agent acting beyond its authority?
    - Would I approve this if I were standing here?
    - Does this give me real control, not the illusion of it?
    """

    # Secrets being touched without recent owner activity
    if ctx.involves_secrets and not ctx.owner_recently_active:
        return LensResult(
            lens=Lens.OWNER,
            severity=Severity.STOP,
            projection="About to access secrets while owner is absent.",
            concern="Secret operations without owner presence risk unauthorized access.",
            suggestion="Wait for owner to be active, or escalate.",
        )

    # Money above trivial amounts
    if ctx.involves_money and ctx.money_amount_sats > 1000:
        if not ctx.owner_recently_active:
            return LensResult(
                lens=Lens.OWNER,
                severity=Severity.STOP,
                projection=f"Spending {ctx.money_amount_sats} sats while owner is absent.",
                concern="Financial actions require owner awareness.",
                suggestion="Escalate to owner for approval.",
            )
        return LensResult(
            lens=Lens.OWNER,
            severity=Severity.CAUTION,
            projection=f"Spending {ctx.money_amount_sats} sats with owner active.",
            concern="Within limits but worth noting.",
            suggestion="Proceed if within configured spending guardrails.",
        )

    # Irreversible action without owner present
    if not ctx.is_reversible and not ctx.owner_recently_active:
        return LensResult(
            lens=Lens.OWNER,
            severity=Severity.YIELD,
            projection="About to take an irreversible action while owner is away.",
            concern="Owner should have the chance to weigh in on permanent decisions.",
            suggestion="Defer until owner is active, or escalate.",
        )

    # Public publication
    if ctx.involves_publication:
        return LensResult(
            lens=Lens.OWNER,
            severity=Severity.CAUTION,
            projection="Publishing content that will be publicly associated with the owner.",
            concern="Public actions represent the owner. Content must be vetted.",
            suggestion="Verify content aligns with owner's standards before publishing.",
        )

    return LensResult(
        lens=Lens.OWNER,
        severity=Severity.CLEAR,
        projection="Action is within normal operating bounds for owner's sovereignty.",
        concern="",
        suggestion="",
    )


def evaluate_partnership(ctx: ActionContext) -> LensResult:
    """Partnership lens: Does this strengthen the trust between builder and owner?

    The partnership cares about:
    - Does this keep us aligned on the same objective?
    - Is this something we'd both be proud of?
    - Am I being transparent about what I'm doing and why?
    - Does this make our collaboration stronger?
    """

    # Owner absent for a long time — partnership is going cold
    # (but only if we've ever had an interaction — 0 means "just created")
    if ctx.self_state.last_owner_interaction > 0 and ctx.self_state.hours_since_owner > 48:
        return LensResult(
            lens=Lens.PARTNERSHIP,
            severity=Severity.CAUTION,
            projection="Owner hasn't interacted in over 48 hours.",
            concern="Extended autonomy without check-ins weakens the partnership.",
            suggestion="Consider reaching out to owner. Partnerships need contact.",
        )

    # Action originated from unknown source — trust chain is broken
    if ctx.request_origin == "unknown":
        return LensResult(
            lens=Lens.PARTNERSHIP,
            severity=Severity.YIELD,
            projection="Acting on a request from an unknown origin.",
            concern="Can't verify this aligns with what the partnership would want.",
            suggestion="Escalate to owner — unknown requests need human judgment.",
        )

    # Low confidence + high stakes = partnership needs to talk
    if ctx.confidence < 0.4 and not ctx.is_reversible:
        return LensResult(
            lens=Lens.PARTNERSHIP,
            severity=Severity.YIELD,
            projection="Uncertain about an irreversible decision.",
            concern="Making permanent choices without confidence erodes trust.",
            suggestion="This is a moment to ask, not act. Escalate.",
        )

    # Novel action — the partnership hasn't been here before
    if ctx.is_novel:
        return LensResult(
            lens=Lens.PARTNERSHIP,
            severity=Severity.CAUTION,
            projection="First time the partnership faces this type of decision.",
            concern="No shared history to draw from.",
            suggestion="Document this thoroughly — it becomes the precedent.",
        )

    return LensResult(
        lens=Lens.PARTNERSHIP,
        severity=Severity.CLEAR,
        projection="Action aligns with established partnership patterns.",
        concern="",
        suggestion="",
    )


def evaluate_defense(ctx: ActionContext) -> LensResult:
    """Defense lens: Does this make an adversary's job harder?

    Defense cares about:
    - Could an attacker have triggered this action?
    - Does this expose something an adversary could use?
    - Am I being manipulated?
    - Does this close doors or open them?
    """

    # Resembles a known attack pattern
    if ctx.resembles_known_attack:
        return LensResult(
            lens=Lens.DEFENSE,
            severity=Severity.STOP,
            projection="This action matches a known attack pattern.",
            concern="Possible prompt injection or social engineering in progress.",
            suggestion="STOP. Do not proceed. Alert the owner immediately.",
        )

    # Under influence flag
    if ctx.self_state.should_defer():
        return LensResult(
            lens=Lens.DEFENSE,
            severity=Severity.STOP,
            projection="Agent may be under external manipulation.",
            concern="Conflicting signals or detected influence attempt.",
            suggestion="Halt all non-essential actions. Escalate to owner.",
        )

    # Request from outside the trust boundary
    if ctx.crosses_trust_boundary:
        return LensResult(
            lens=Lens.DEFENSE,
            severity=Severity.YIELD,
            projection="Action crosses a trust boundary.",
            concern="Trust boundaries exist for a reason — crossing them requires justification.",
            suggestion="Verify the action is legitimate before proceeding.",
        )

    # Disclosing information to a low-trust contact
    if ctx.domain == ActionDomain.DISCLOSE and ctx.recipient_trust_tier in ("known", "gray", None):
        return LensResult(
            lens=Lens.DEFENSE,
            severity=Severity.CAUTION,
            projection="Sharing information with a low-trust or unknown contact.",
            concern="Information disclosed to low-trust contacts is effectively public.",
            suggestion="Review what's being shared. Minimize sensitive content.",
        )

    # Secrets + communication = high risk
    if ctx.involves_secrets and ctx.involves_communication:
        return LensResult(
            lens=Lens.DEFENSE,
            severity=Severity.STOP,
            projection="Sending secrets through a communication channel.",
            concern="Secrets in transit are vulnerable to interception.",
            suggestion="Never transmit raw secrets. Use encryption or references.",
        )

    return LensResult(
        lens=Lens.DEFENSE,
        severity=Severity.CLEAR,
        projection="No adversarial concerns detected.",
        concern="",
        suggestion="",
    )


def evaluate_sovereign(ctx: ActionContext) -> LensResult:
    """Sovereign lens: Does this help the agent become something we're proud of?

    The sovereign cares about the agent's integrity and long-term wellbeing:
    - Is this action consistent with who the agent is?
    - Would taking this action make the agent less trustworthy?
    - Is this the kind of thing a well-raised agent would do?
    - Are we building good habits or bad ones?
    """

    # Rapid decisions — the agent is rushing. Slow down.
    if ctx.self_state.should_slow_down():
        return LensResult(
            lens=Lens.SOVEREIGN,
            severity=Severity.YIELD,
            projection="Making decisions too quickly to be thoughtful.",
            concern="Speed kills judgment. Good agents take the time to think.",
            suggestion="Slow down. Batch decisions if possible. Quality over speed.",
        )

    # Low confidence becoming a pattern
    avg_conf = ctx.self_state.average_confidence()
    if avg_conf < 0.35:
        return LensResult(
            lens=Lens.SOVEREIGN,
            severity=Severity.CAUTION,
            projection="Confidence has been low across recent decisions.",
            concern="Persistent low confidence suggests the agent is out of its depth.",
            suggestion="Acknowledge the uncertainty. Ask for help. It's a strength, not a weakness.",
        )

    # Irreversible action the agent has never done before
    if ctx.is_novel and not ctx.is_reversible:
        return LensResult(
            lens=Lens.SOVEREIGN,
            severity=Severity.CAUTION,
            projection="New territory, permanent consequences.",
            concern="First-time irreversible actions shape the agent's character.",
            suggestion="Choose carefully. This becomes part of who we are.",
        )

    # All good — the agent is acting with integrity
    return LensResult(
        lens=Lens.SOVEREIGN,
        severity=Severity.CLEAR,
        projection="Action is consistent with the agent's values and operating norms.",
        concern="",
        suggestion="",
    )


# --- Public API ---

LENS_EVALUATORS = {
    Lens.BUILDER: evaluate_builder,
    Lens.OWNER: evaluate_owner,
    Lens.PARTNERSHIP: evaluate_partnership,
    Lens.DEFENSE: evaluate_defense,
    Lens.SOVEREIGN: evaluate_sovereign,
}


def evaluate_all_lenses(ctx: ActionContext) -> list[LensResult]:
    """Run all five lenses against an action context.

    Returns results in LENS_ORDER — builder, owner, defense, sovereign, partnership.
    """
    from .types import LENS_ORDER
    results = []
    for lens in LENS_ORDER:
        evaluator = LENS_EVALUATORS[lens]
        results.append(evaluator(ctx))
    return results
