from __future__ import annotations

from health_client import AccountSnapshot, HealthStatus

FIVE_HOUR_WARNING_THRESHOLD_PCT: int = 15
SEVEN_DAY_WARNING_THRESHOLD_PCT: int = 5

WINDOW_5H: str = "5h"
WINDOW_7D: str = "7d"


def breached_windows(
    snapshot: AccountSnapshot,
    *,
    five_hour_threshold_pct: int = FIVE_HOUR_WARNING_THRESHOLD_PCT,
    seven_day_threshold_pct: int = SEVEN_DAY_WARNING_THRESHOLD_PCT,
) -> frozenset[str]:
    if snapshot.status != HealthStatus.OK:
        return frozenset()

    breached: set[str] = set()

    if snapshot.primary_used_pct is not None and _remaining_pct(
        snapshot.primary_used_pct
    ) < five_hour_threshold_pct:
        breached.add(WINDOW_5H)

    if snapshot.secondary_used_pct is not None and _remaining_pct(
        snapshot.secondary_used_pct
    ) < seven_day_threshold_pct:
        breached.add(WINDOW_7D)

    return frozenset(breached)


RESET_DROP_PCT: int = 20
RESET_FLOOR_PCT: int = 20


def window_reset(previous_used_pct: int | None, used_pct: int | None) -> bool:
    """A window reset shows up as usage falling back by a large step.

    With no earlier reading — the first poll after a restart — usage sitting
    below the floor is only reachable through a reset.
    """
    if used_pct is None:
        return False
    if used_pct <= RESET_FLOOR_PCT:
        return True
    if previous_used_pct is None:
        return False
    return previous_used_pct - used_pct >= RESET_DROP_PCT


def _remaining_pct(used_pct: int) -> int:
    return 100 - min(max(used_pct, 0), 100)
