"""
Sell/Reduce triggers (spec §28 / docs/SCORING.md §6). Each trigger is an independent boolean
check over metric-history deltas, never price momentum alone. `SellTriggerInputs` is built by
the caller from `metric_history` (real system) — see engines/recommendation/engine.py for how
it's combined with the score-table recommendation.
"""
from __future__ import annotations

from dataclasses import dataclass


@dataclass(frozen=True)
class SellTriggerInputs:
    price_above_overvalued_band: bool = False
    roic_declining_3q: bool = False
    operating_margin_declining_3q: bool = False
    fcf_declining_3q: bool = False
    revenue_declining_2q: bool = False
    eps_declining_2q: bool = False
    net_debt_to_ebitda_rising_3q: bool = False
    interest_coverage_declining_3q: bool = False
    dividend_cut: bool = False
    diluted_shares_up_over_3pct_yoy: bool = False
    guidance_reduced: bool = False
    consensus_estimate_down_over_5pct_90d: bool = False


# name -> (input attribute, severity 1-3; 3 = most severe, can alone force REDUCE)
_TRIGGER_DEFS: list[tuple[str, str, int]] = [
    ("EXTREME_OVERVALUATION", "price_above_overvalued_band", 2),
    ("ROIC_DETERIORATION", "roic_declining_3q", 2),
    ("MARGIN_DETERIORATION", "operating_margin_declining_3q", 2),
    ("FCF_DETERIORATION", "fcf_declining_3q", 2),
    ("REVENUE_DETERIORATION", "revenue_declining_2q", 2),
    ("EPS_DETERIORATION", "eps_declining_2q", 2),
    ("DEBT_DETERIORATION", "net_debt_to_ebitda_rising_3q", 2),
    ("INTEREST_COVERAGE_DETERIORATION", "interest_coverage_declining_3q", 2),
    ("DIVIDEND_CUT", "dividend_cut", 3),
    ("SHARE_DILUTION", "diluted_shares_up_over_3pct_yoy", 1),
    ("GUIDANCE_REDUCTION", "guidance_reduced", 2),
    ("ESTIMATE_REDUCTION", "consensus_estimate_down_over_5pct_90d", 1),
]

# Not implemented as automated triggers in this codebase — require qualitative signal the
# current data model doesn't carry. Listed for honesty (see docs/SPEC_COVERAGE.md), never faked.
NOT_IMPLEMENTED_TRIGGERS = [
    "COMPETITIVE_ADVANTAGE_DETERIORATION", "ACCOUNTING_CONCERNS", "REGULATORY_RISK",
    "MANAGEMENT_CAPITAL_ALLOCATION_DETERIORATION",
]


def evaluate_sell_triggers(inputs: SellTriggerInputs) -> tuple[list[str], int]:
    """Returns (fired trigger names, total severity score)."""
    fired = []
    severity = 0
    for name, attr, sev in _TRIGGER_DEFS:
        if getattr(inputs, attr):
            fired.append(name)
            severity += sev
    return fired, severity


def sell_ceiling_from_severity(severity: int):
    """The MAXIMUM (best) recommendation allowed once triggers have fired — imported lazily to
    avoid a circular import with bands.py at module load time."""
    from app.engines.recommendation.bands import Recommendation

    if severity == 0:
        return None  # no ceiling — table recommendation stands unmodified
    if severity >= 7:
        return Recommendation.STRONG_SELL
    if severity >= 5:
        return Recommendation.SELL
    if severity >= 2:
        return Recommendation.REDUCE
    return Recommendation.HOLD  # a single low-severity trigger caps upside at HOLD, not lower
