"""Grades the stock level of a SKU.

The score follows a smooth piecewise-linear curve (see
``INVENTORY_SCORE_ANCHORS``) so that moderate stock levels earn moderate
scores instead of collapsing toward zero. Inventory informs the decision but
is weighted so it cannot dominate it.
"""
from __future__ import annotations

from dataclasses import dataclass

from ....constants import constants as C
from ....utils.helpers import piecewise_score


@dataclass
class InventoryAnalysis:
    stock: int
    available_stock: int
    health: str
    score: float  # 0-100

    def to_dict(self) -> dict:
        return {
            "stock": self.stock,
            "availableStock": self.available_stock,
            "health": self.health,
            "score": round(self.score, 2),
        }


class InventoryAnalyzer:
    """Single responsibility: map stock levels to a health label and score."""

    def analyze(self, stock: int, available_stock: int | None = None) -> InventoryAnalysis:
        available = stock if available_stock is None else available_stock
        effective = max(0, min(stock, available) if available else stock)

        return InventoryAnalysis(
            stock=stock,
            available_stock=available,
            health=self._health(effective),
            score=piecewise_score(effective, C.INVENTORY_SCORE_ANCHORS),
        )

    @staticmethod
    def _health(stock: int) -> str:
        """Bands: 0 Out of Stock / 1-10 Very Low / 11-30 Low / 31-100 Medium /
        101-500 High / 500+ Excellent."""
        if stock <= 0:
            return C.INVENTORY_HEALTH["OUT_OF_STOCK"]
        if stock > C.INVENTORY_EXCELLENT:
            return C.INVENTORY_HEALTH["EXCELLENT"]
        if stock > C.INVENTORY_HIGH:
            return C.INVENTORY_HEALTH["HIGH"]
        if stock > C.INVENTORY_MEDIUM:
            return C.INVENTORY_HEALTH["MEDIUM"]
        if stock > C.INVENTORY_VERY_LOW:
            return C.INVENTORY_HEALTH["LOW"]
        return C.INVENTORY_HEALTH["VERY_LOW"]
