"""
Migration + WFM scenario — the no-AI business case.

Current state → Genesys Cloud CX migration, NA users migrated onto
Genesys WFM, WFM implemented for APAC (ANZ + ASIA). Migration and WFM
are included in the base implementation price (the verbatim PS +
training), so the only cost lines are the existing-platform run-off,
the licence ramp, and base PS — no token consumption, no AI
implementation labour. The only benefits kept are the deck's verbatim
WFM lines for the regions in WFM scope.

Single source of truth behind ``notebooks/ctm_migration_wfm.ipynb``
(served with Mercury) — the presentation layer holds no math. All
primitives come from :mod:`tokencalc.appendix4`; this module only
scopes and extrapolates.
"""

from __future__ import annotations

import math

import pandas as pd

from . import appendix4 as a4

#: WFM scope in this scenario. NA is a migration off its existing
#: WFM-like tool (verbatim benefit $0 — "has similar feature"); ANZ and
#: ASIA are new implementations ("APAC"); EMEA is out of scope, so the
#: deck's EMEA WFM benefit line is dropped.
DEFAULT_WFM_REGIONS = ["NA", "ANZ", "ASIA"]


def wfm_benefits_by_year(
    benefit_rollout, regions: list[str] | None = None
) -> pd.DataFrame:
    """Verbatim WFM benefits for the scoped regions, phased on the
    deck's deployment schedule (realize = impl + 3 months, inclusive).

    Long DataFrame: region, capability, year, benefit — the WFM slice
    of :func:`tokencalc.appendix4.benefits_by_year`.
    """
    scope = DEFAULT_WFM_REGIONS if regions is None else regions
    df = a4.benefits_by_year(benefit_rollout)
    return df[(df["capability"] == "WFM")
              & (df["region"].isin(scope))].reset_index(drop=True)


def wfm_annual_runrate(regions: list[str] | None = None) -> float:
    """Sum of the verbatim WFM *annual* values for the scoped regions."""
    scope = DEFAULT_WFM_REGIONS if regions is None else regions
    return float(sum(annual for (r, c), (annual, _t) in
                     a4.VERBATIM_BENEFITS.items()
                     if c == "WFM" and r in scope))


def runrate_saving_annual(
    licence_annual: float | None = None,
    regions: list[str] | None = None,
    baseline_annual: float | None = None,
    managed_annual: float = 0.0,
) -> float:
    """Steady-state annual saving once term contracts end and the ramp
    is over: (baseline − licence run-rate − managed services) + scoped
    WFM annual values.

    Defaults are the deck frame (deck licence rate, no managed
    services); the contracted frame passes ``a4.MANAGED_SERVICES_ANNUAL``.
    """
    lic = a4.TCO_VERBATIM["ccaas_annual"] if licence_annual is None else licence_annual
    base = a4.TCO_VERBATIM["current_annual"] if baseline_annual is None else baseline_annual
    return (base - lic - managed_annual) + wfm_annual_runrate(regions)


def runrate_breakeven_label(
    net_by_year: dict[int, float], runrate_annual: float
) -> str:
    """Payback label, extrapolated past the model window at a run-rate.

    Inside 2026-28 this defers to :func:`tokencalc.appendix4.payback_label`;
    a deficit at end-2028 fills at ``runrate_annual`` per year.
    """
    deficit = -sum(net_by_year[y] for y in a4.YEARS)
    if deficit <= 0:
        return a4.payback_label(net_by_year)
    if runrate_annual <= 0:
        return "never at current run-rate"
    m = 12 * len(a4.YEARS) + math.ceil(12 * deficit / runrate_annual)
    return f"{m} months (~{a4.month_label(m)}, extrapolated)"
