"""
AkDevz AI Market Intelligence — Support & Resistance Engine
Pivot points, PDH/PDL, Camarilla levels, and horizontal zone clustering.
"""
from typing import Dict, List, Any

class SupportResistanceEngine:
    @staticmethod
    def calculate_daily_pivots(high: float, low: float, close: float) -> Dict[str, float]:
        """
        Calculates Standard Floor Pivots and Camarilla Levels.
        """
        p = (high + low + close) / 3.0
        r1 = (2.0 * p) - low
        s1 = (2.0 * p) - high
        r2 = p + (high - low)
        s2 = p - (high - low)
        r3 = high + 2.0 * (p - low)
        s3 = low - 2.0 * (high - p)

        # Camarilla pivots (crucial for mean reversion and breakouts)
        diff = high - low
        h4 = close + (diff * 1.1 / 2.0)
        h3 = close + (diff * 1.1 / 4.0)
        l3 = close - (diff * 1.1 / 4.0)
        l4 = close - (diff * 1.1 / 2.0)

        return {
            "pivot": round(p, 2),
            "r1": round(r1, 2),
            "s1": round(s1, 2),
            "r2": round(r2, 2),
            "s2": round(s2, 2),
            "r3": round(r3, 2),
            "s3": round(s3, 2),
            "cam_h3": round(h3, 2),
            "cam_h4": round(h4, 2),
            "cam_l3": round(l3, 2),
            "cam_l4": round(l4, 2),
            "pdh": round(high, 2),
            "pdl": round(low, 2),
            "pdc": round(close, 2),
        }

    @staticmethod
    def cluster_zones(levels: List[float], tolerance_pct: float = 0.20) -> List[Dict[str, Any]]:
        """
        Groups nearby discrete price levels within tolerance into consolidated zones.
        """
        if not levels:
            return []

        sorted_levels = sorted([lvl for lvl in levels if lvl > 0])
        zones = []
        current_cluster = [sorted_levels[0]]

        for lvl in sorted_levels[1:]:
            cluster_avg = sum(current_cluster) / len(current_cluster)
            diff_pct = abs(lvl - cluster_avg) / cluster_avg * 100.0

            if diff_pct <= tolerance_pct:
                current_cluster.append(lvl)
            else:
                zones.append({
                    "price_low": round(min(current_cluster), 2),
                    "price_high": round(max(current_cluster), 2),
                    "touch_count": len(current_cluster),
                    "strength_score": min(10.0, 4.0 + (len(current_cluster) * 1.5))
                })
                current_cluster = [lvl]

        if current_cluster:
            zones.append({
                "price_low": round(min(current_cluster), 2),
                "price_high": round(max(current_cluster), 2),
                "touch_count": len(current_cluster),
                "strength_score": min(10.0, 4.0 + (len(current_cluster) * 1.5))
            })

        return zones
