"""
Measurable proxies for the Competitive Advantage score (spec §21): persistence/stability of
ROIC, margins, revenue and FCF over a trailing window, each turned into a 0-100 "stability
score" via coefficient of variation (lower CoV = more persistent = higher score), plus optional
disclosed-only proxies. Nothing here infers a moat that isn't backed by a measured series.
"""
from __future__ import annotations

from typing import Optional, Sequence

import numpy as np

from app.engines.metrics.formula_utils import trend_slope


def stability_score(values: Sequence[Optional[float]], min_points: int = 4) -> Optional[float]:
    clean = [v for v in values if v is not None]
    if len(clean) < min_points:
        return None
    arr = np.asarray(clean, dtype=float)
    mean = np.mean(arr)
    if mean == 0:
        return None
    cov = float(np.std(arr, ddof=1) / abs(mean))
    # Map CoV in [0, 1.5+] to a 0-100 score, saturating at the extremes. CoV 0 -> 100, CoV >= 1.0 -> ~0.
    score = max(0.0, 100.0 * (1.0 - min(cov, 1.0)))
    return score


def asset_light_score(invested_capital_to_revenue: Optional[float]) -> Optional[float]:
    """Lower Invested Capital / Revenue -> more asset-light -> higher proxy score.
    Calibrated so ratio 0.0 -> 100, ratio >= 2.0 -> ~0 (heavy industrials territory)."""
    if invested_capital_to_revenue is None or invested_capital_to_revenue < 0:
        return None
    return max(0.0, 100.0 * (1.0 - min(invested_capital_to_revenue / 2.0, 1.0)))


def pricing_power_score(gross_margin_history: Sequence[Optional[float]], min_points: int = 4) -> Optional[float]:
    """A rising or flat gross-margin trend while a company keeps growing is a measurable (if
    imperfect) pricing-power proxy: a business with no pricing power sees margins compress under
    input-cost inflation and competitive pressure. `trend_slope` is already normalized by the
    series' mean, so the mapping below is on a comparable scale across companies. This is
    deliberately the ONLY additional proxy the StockLab overhaul audit added on top of the
    original persistence proxies — see docs/COMPETITIVE_ADVANTAGE.md for the full list of proxies
    the spec described (recurring revenue %, brand, switching costs, network effects, market
    share trend) that are NOT implemented because they require data this platform's financial
    statement providers do not supply (subscription-mix disclosure, survey/brand data, market-size
    denominators) — adding a numeric-looking proxy for those without real input data would be
    inventing a moat score, which spec §21 and this audit both explicitly forbid.
    """
    clean = [v for v in gross_margin_history if v is not None]
    if len(clean) < min_points:
        return None
    slope = trend_slope(clean)
    if slope is None:
        return None
    # normalized slope units are "fraction of mean per period" — a +/-10% move end-to-end over
    # the series maps to roughly +/-0.02..0.03 per period for a typical 4-8 point series; scale so
    # a flat-to-rising trend scores well and a clearly deteriorating one scores poorly.
    return max(0.0, min(100.0, 50.0 + slope * 1000.0))


def build_competitive_advantage_proxies(
    roic_history: Sequence[Optional[float]],
    gross_margin_history: Sequence[Optional[float]],
    operating_margin_history: Sequence[Optional[float]],
    revenue_history: Sequence[Optional[float]],
    fcf_history: Sequence[Optional[float]],
    invested_capital_to_revenue: Optional[float] = None,
    customer_concentration_pct: Optional[float] = None,  # % of revenue from top customer(s), if disclosed
) -> dict[str, Optional[float]]:
    proxies: dict[str, Optional[float]] = {
        "roic_persistence": stability_score(roic_history),
        "gross_margin_persistence": stability_score(gross_margin_history),
        "operating_margin_persistence": stability_score(operating_margin_history),
        "revenue_stability": stability_score(revenue_history),
        "fcf_stability": stability_score(fcf_history),
        "asset_light": asset_light_score(invested_capital_to_revenue),
        "pricing_power": pricing_power_score(gross_margin_history),
    }
    if customer_concentration_pct is not None:
        # Lower concentration = less customer risk = higher proxy score.
        proxies["low_customer_concentration"] = max(0.0, 100.0 - customer_concentration_pct)
    return proxies
