"""
Client overlay — Variant 4's personalization layer.

The verbatim anchor is Forrester's *composite organization* (2,000 agents,
20M contacts, 30% growth). This module rescales that composite to a client's
size: a 🟡 **first-order linear rescale**, answering "what does the composite
look like at your scale?", not "what is your TEI?".

Each verbatim row is tied to the driver that dominates its derivation in the
PDF (see ``BENEFIT_DRIVERS``/``COST_DRIVERS``); rows scale linearly with
their driver, project-based costs stay fixed. The client's growth rate
re-bases the composite's Y1→Y3 trajectory (which embeds 30% YoY).

``overlay_rows(COMPOSITE)`` is the identity — it reproduces the verbatim
numbers exactly, so headless widget defaults form the published-study
reproduction the gate expects. The anchor is never mutated: every function
deep-copies.
"""

from __future__ import annotations

from copy import deepcopy
from dataclasses import dataclass

from .anchor import ASSUMPTIONS, BENEFITS_VERBATIM, COSTS_VERBATIM


@dataclass(frozen=True)
class ClientDrivers:
    """Client inputs; defaults are the Forrester composite (identity overlay)."""

    agents_fte: int = ASSUMPTIONS["agents_fte"]                    # 2,000 (+200 supervisors at 10:1)
    annual_contacts_y1: int = ASSUMPTIONS["annual_contacts_y1"]    # 20M
    growth_rate: float = ASSUMPTIONS["growth_rate"]                # 0.30 YoY
    discount_rate: float = ASSUMPTIONS["discount_rate"]            # 0.10


COMPOSITE = ClientDrivers()


#: 🟡 Which driver each verbatim row scales with, per its PDF derivation.
BENEFIT_DRIVERS: dict[str, str] = {
    "ai_contact_resolution":      "contacts",   # AHT × volume → contact-driven
    "ai_content_sentiment":       "contacts",   # per-call summaries/QA → contact-driven
    "ai_forecasting_supervision": "agents",     # FTE optimization + supervisor span
    "data_driven_profit_lift":    "contacts",   # 🔴 proxy — revenue-driven in the PDF;
                                                #    outbound volume is the nearest linear driver
    "legacy_solution_savings":    "agents",     # $/agent-month licences (supervisors follow 10:1)
}
COST_DRIVERS: dict[str, str] = {
    "amazon_connect_usage":       "contacts",   # per-minute/per-message consumption
    "implementation_migration":   "fixed",      # project-based — does not scale
    "ongoing_management":         "fixed",      # small fixed team
}


def scale_factor(driver: str, d: ClientDrivers) -> float:
    """Linear size ratio vs the composite for one driver kind."""
    if driver == "contacts":
        return d.annual_contacts_y1 / ASSUMPTIONS["annual_contacts_y1"]
    if driver == "agents":
        return d.agents_fte / ASSUMPTIONS["agents_fte"]
    if driver == "fixed":
        return 1.0
    raise KeyError(f"Unknown driver: {driver!r}")


def growth_multiplier(year_index: int, growth_rate: float) -> float:
    """
    Re-base the composite's Y1→Y3 trajectory on the client's growth.

    The verbatim year values already embed the composite's 30% YoY growth;
    dividing it out and compounding the client's rate preserves the
    composite's *shape* while adopting the client's slope. Year 1 → 1.0.
    """
    composite_g = ASSUMPTIONS["growth_rate"]
    return ((1.0 + growth_rate) / (1.0 + composite_g)) ** (year_index - 1)


def overlay_rows(d: ClientDrivers = COMPOSITE) -> tuple[list[dict], list[dict]]:
    """
    Deep-copied (benefits, costs) rows rescaled to the client's drivers.

    Non-fixed rows: ``year_values[n] ×= scale_factor × growth_multiplier(n)``.
    Fixed rows keep their year values and ``initial`` unchanged (no growth
    re-base either — they are project/team costs, not volume costs).
    Risk factors, labels, and notes are untouched.
    """

    def _apply(rows: list[dict], drivers: dict[str, str]) -> list[dict]:
        out = []
        for raw in rows:
            row = deepcopy(raw)
            driver = drivers[row["field_key"]]
            if driver != "fixed":
                s = scale_factor(driver, d)
                row["year_values"] = {
                    k: float(v) * s * growth_multiplier(int(k), d.growth_rate)
                    for k, v in row["year_values"].items()
                }
                if row.get("initial"):
                    row["initial"] = float(row["initial"]) * s
            out.append(row)
        return out

    return (_apply(BENEFITS_VERBATIM, BENEFIT_DRIVERS),
            _apply(COSTS_VERBATIM, COST_DRIVERS))
