"""
Industry Applicability Matrix (spec §13).

Not every metric is meaningful for every industry (e.g. Debt/EBITDA and Current Ratio for a
bank, EV/EBITDA for an insurer). Rather than let a metric silently compute a misleading number,
each (metric, industry) pair maps to an Applicability status; the metrics engine and scoring
engine both consult this before computing/including a metric.

Industries are identified by a small set of canonical GICS-like sector codes here; the full
industry taxonomy lives in `app/models/reference.py` / the `industries` table — this module maps
by SECTOR because applicability rules are almost always sector-wide (all banks, not just
"regional banks"), with room for industry-level overrides in `INDUSTRY_OVERRIDES` below.
"""
from __future__ import annotations

from app.engines.types import Applicability

SECTOR_FINANCIALS = "FINANCIALS"
SECTOR_INSURANCE = "INSURANCE"
SECTOR_REITS = "REAL_ESTATE"
SECTOR_UTILITIES = "UTILITIES"
SECTOR_ENERGY = "ENERGY"
SECTOR_BIOTECH = "BIOTECH"
SECTOR_DEFAULT = "DEFAULT"

# Metrics that are structurally distorted or undefined for certain sectors.
# Missing (sector, metric) pairs default to APPLICABLE.
_SECTOR_METRIC_RULES: dict[str, dict[str, Applicability]] = {
    SECTOR_FINANCIALS: {
        "debt_to_ebitda": Applicability.NOT_MEANINGFUL,
        "net_debt_to_ebitda": Applicability.NOT_MEANINGFUL,
        "current_ratio": Applicability.NOT_MEANINGFUL,
        "ev_to_ebitda": Applicability.NOT_MEANINGFUL,
        "ev_to_fcf": Applicability.NOT_MEANINGFUL,
        "interest_coverage": Applicability.NOT_MEANINGFUL,
        "capex_to_revenue": Applicability.LIMITED,
        "fcf_margin": Applicability.LIMITED,
        "fcf_yield": Applicability.LIMITED,
        "roic": Applicability.LIMITED,  # invested capital concept doesn't map cleanly to a bank
        "roic_minus_wacc": Applicability.LIMITED,
    },
    SECTOR_INSURANCE: {
        "debt_to_ebitda": Applicability.NOT_MEANINGFUL,
        "net_debt_to_ebitda": Applicability.NOT_MEANINGFUL,
        "current_ratio": Applicability.NOT_MEANINGFUL,
        "ev_to_ebitda": Applicability.NOT_MEANINGFUL,
        "interest_coverage": Applicability.LIMITED,
        "roic": Applicability.LIMITED,
    },
    SECTOR_REITS: {
        "capex_to_revenue": Applicability.LIMITED,  # capex conflated with acquisitions
        "fcf_payout_ratio": Applicability.LIMITED,  # FFO is the REIT-native payout base, not FCF
        "roic": Applicability.LIMITED,
    },
    SECTOR_UTILITIES: {
        "capex_to_revenue": Applicability.LIMITED,  # structurally high, not a quality signal here
        "fcf_yield": Applicability.LIMITED,
    },
    SECTOR_ENERGY: {
        "gross_margin": Applicability.LIMITED,  # commodity accounting varies widely
    },
    SECTOR_BIOTECH: {
        "pe": Applicability.NOT_MEANINGFUL,
        "forward_pe": Applicability.LIMITED,
        "peg": Applicability.NOT_MEANINGFUL,
        "ev_to_fcf": Applicability.NOT_MEANINGFUL,
        "p_fcf": Applicability.NOT_MEANINGFUL,
        "fcf_payout_ratio": Applicability.NOT_MEANINGFUL,
        "roic": Applicability.LIMITED,  # frequently pre-profit
    },
}


def get_applicability(metric_key: str, sector_code: str) -> Applicability:
    rules = _SECTOR_METRIC_RULES.get(sector_code.upper())
    if not rules:
        return Applicability.APPLICABLE
    return rules.get(metric_key, Applicability.APPLICABLE)
