from storai.schema.types import Insight


def growth_rule(metric):
    threshold = 0.05

    if abs(metric.value) >= threshold:
        score = metric.value

        # Enhanced context with data characteristics
        context = metric.context.copy() if metric.context else {}

        # Add growth magnitude classification
        abs_score = abs(score)
        if abs_score >= 0.20:
            context["growth_magnitude"] = "high"
            context["magnitude_desc"] = "exceptional" if score > 0 else "severe"
        elif abs_score >= 0.10:
            context["growth_magnitude"] = "moderate"
            context["magnitude_desc"] = "significant" if score > 0 else "notable"
        else:
            context["growth_magnitude"] = "low"
            context["magnitude_desc"] = "modest" if score > 0 else "mild"

        # Add directional context
        context["direction"] = "growth" if score > 0 else "decline"
        context["direction_word"] = "increase" if score > 0 else "decrease"

        # Add volatility indicators if available
        if hasattr(metric, "volatility") and metric.volatility is not None:
            context["volatility"] = metric.volatility
            context["volatility_desc"] = (
                "high"
                if metric.volatility > 0.15
                else "moderate" if metric.volatility > 0.05 else "low"
            )

        return Insight(
            type="growth",
            name=metric.name,
            score=score,
            message_data=context,
        )


def contribution_rule(metric):
    threshold = 0.30

    entity = metric.context.get("entity")
    num_groups = metric.context.get("num_groups", 0)

    # Skip trivial cases
    if entity is None:
        return None

    if num_groups < 2:
        return None

    if metric.value >= threshold:
        # Enhanced context for dominance insights
        context = metric.context.copy() if metric.context else {}
        share_percent = metric.value * 100

        # Add market position context
        if share_percent >= 70:
            context["market_position"] = "near-monopoly status"
            context["position_strength"] = "dominant"
        elif share_percent >= 50:
            context["market_position"] = "market leadership"
            context["position_strength"] = "strong"
        elif share_percent >= 30:
            context["market_position"] = "significant market presence"
            context["position_strength"] = "moderate"
        else:
            context["market_position"] = "notable market share"
            context["position_strength"] = "modest"

        # Add competitive context
        context["competitive_landscape"] = (
            "highly concentrated"
            if num_groups <= 3
            else "moderately competitive" if num_groups <= 6 else "fragmented"
        )

        return Insight(
            type="dominance",
            name=metric.name,
            score=float(metric.value),
            message_data=context,
        )


def rate_rule(metric):
    threshold = 0.05

    if metric.value >= threshold:
        context = metric.context.copy() if metric.context else {}

        # Add rate context
        rate_value = metric.value * 100
        if rate_value >= 50:
            context["rate_category"] = "high"
            context["rate_desc"] = "exceptionally high"
        elif rate_value >= 20:
            context["rate_category"] = "moderate-high"
            context["rate_desc"] = "above average"
        elif rate_value >= 5:
            context["rate_category"] = "moderate"
            context["rate_desc"] = "standard"
        else:
            context["rate_category"] = "low"
            context["rate_desc"] = "minimal"

        return Insight(
            type="rate",
            name=metric.name,
            score=metric.value,
            message_data=context,
        )


def rate_change_rule(metric):
    threshold = 0.05

    if abs(metric.value) >= threshold:
        context = metric.context.copy() if metric.context else {}

        # Add change magnitude context
        abs_change = abs(metric.value) * 100
        if abs_change >= 20:
            context["change_magnitude"] = "dramatic"
        elif abs_change >= 10:
            context["change_magnitude"] = "significant"
        elif abs_change >= 5:
            context["change_magnitude"] = "moderate"
        else:
            context["change_magnitude"] = "mild"

        # Add directional context
        context["change_direction"] = (
            "improvement" if metric.value > 0 else "deterioration"
        )
        context["change_sentiment"] = "positive" if metric.value > 0 else "negative"

        return Insight(
            type="rate_change",
            name=metric.name,
            score=abs(metric.value),
            message_data=context,
        )


def trend_rule(metric):
    # Threshold: 1% average change per period
    threshold = 0.01

    if abs(metric.value) >= threshold:
        context = metric.context.copy() if metric.context else {}

        # Add trend strength context
        abs_trend = abs(metric.value)
        if abs_trend >= 0.05:
            context["trend_strength"] = "strong"
            context["momentum"] = "robust"
        elif abs_trend >= 0.02:
            context["trend_strength"] = "moderate"
            context["momentum"] = "steady"
        else:
            context["trend_strength"] = "weak"
            context["momentum"] = "gentle"

        # Add stability context
        if hasattr(metric, "stability") and metric.stability is not None:
            context["trend_stability"] = (
                "stable"
                if metric.stability > 0.8
                else "volatile" if metric.stability < 0.4 else "moderate"
            )
            context["volatility_desc"] = (
                "consistent"
                if metric.stability > 0.8
                else "fluctuating" if metric.stability < 0.4 else "mixed"
            )

        # Add duration context if available
        if hasattr(metric, "duration_periods") and metric.duration_periods is not None:
            context["trend_duration"] = metric.duration_periods
            context["trend_maturity"] = (
                "established"
                if metric.duration_periods > 6
                else "emerging" if metric.duration_periods > 3 else "nascent"
            )

        return Insight(
            type="trend",
            name=metric.name,
            score=metric.value,
            message_data=context,
        )


RULES = {
    "growth": growth_rule,
    "contribution": contribution_rule,
    "rate": rate_rule,
    "rate_change": rate_change_rule,
    "trend": trend_rule,
}
