"""
H1 market structure detection — port fedele da V15.

Classifies the H1 frame into BULLISH_EXPANSION / BEARISH_EXPANSION /
RANGING using:
  - HH/LL detection on last 7 bars vs 5 prior, with ATR-scaled threshold
  - HH/HL counts on last 6 bars (h1_struct_bull / h1_struct_bear flags)
  - bullish/bearish close on the latest bar to disambiguate HH+LL ties

The asset-specific multiplier (STRUCT_THRESHOLDS) widens the band for
indices and metals (deeper swings) and tightens it for FX (smaller).
"""

from __future__ import annotations

from typing import Any

import pandas as pd

from analysis.indicators.atr import calc_atr


# Asset-specific multiplier on H1 ATR for the structure threshold.
# Ported as-is from V15. "default" used for unknown roots.
STRUCT_THRESHOLDS: dict[str, float] = {
    # Index micros — deeper swings
    "MES": 0.20, "MNQ": 0.20, "MYM": 0.20,
    "ES":  0.20, "NQ":  0.20, "YM":  0.20, "RTY": 0.20,
    # Metals
    "MGC": 0.25, "GC":  0.25,
    # Energy
    "MCL": 0.20, "CL":  0.20,
    # FX micros + full
    "6E":  0.15, "6B":  0.15, "6A":  0.15, "6J":  0.15, "6C":  0.15,
    # Fallback
    "default": 0.15,
}


def calc_market_structure(
    df1: pd.DataFrame,
    symbol: str,
    struct_thresholds: dict[str, float] | None = None,
) -> dict[str, Any]:
    """
    Returns a dict with:
        market_structure: "BULLISH_EXPANSION" | "BEARISH_EXPANSION" | "RANGING"
        trend_maturity:   max consecutive up/down H1 closes (last 5)
        h1_struct_bull:   bool — HH+HL pattern on last 6 H1 bars
        h1_struct_bear:   bool — LH+LL pattern on last 6 H1 bars
        atr_h1:           current H1 ATR (used by upstream regime detection)

    Args:
        df1: H1 OHLCV DataFrame (>= 7 bars).
        symbol: instrument root for threshold lookup.
        struct_thresholds: override map; defaults to module-level
                           STRUCT_THRESHOLDS.
    """
    thresholds = struct_thresholds or STRUCT_THRESHOLDS

    atr_h1_s = calc_atr(df1)
    atr_h1_cur = atr_h1_s.iloc[-1]
    str_mult = thresholds.get(symbol, thresholds.get("default", 0.15))
    struct_thr = str_mult * atr_h1_cur

    current_or_prev_high = max(df1["high"].iloc[-1], df1["high"].iloc[-2])
    past_highs = df1["high"].iloc[-7:-2].max()
    hh = current_or_prev_high > past_highs + struct_thr

    current_or_prev_low = min(df1["low"].iloc[-1], df1["low"].iloc[-2])
    past_lows = df1["low"].iloc[-7:-2].min()
    ll = current_or_prev_low < past_lows - struct_thr

    if hh and ll:
        struct = (
            "BULLISH_EXPANSION"
            if df1["close"].iloc[-1] > df1["open"].iloc[-1]
            else "BEARISH_EXPANSION"
        )
    elif hh:
        struct = "BULLISH_EXPANSION"
    elif ll:
        struct = "BEARISH_EXPANSION"
    else:
        struct = "RANGING"

    h1_up = sum(
        1 for i in range(-1, -6, -1)
        if df1["close"].iloc[i] > df1["close"].iloc[i - 1]
    )
    h1_down = sum(
        1 for i in range(-1, -6, -1)
        if df1["close"].iloc[i] < df1["close"].iloc[i - 1]
    )

    h1_highs = [df1["high"].iloc[i] for i in range(-6, 0)]
    h1_lows = [df1["low"].iloc[i] for i in range(-6, 0)]
    hh_count = sum(1 for i in range(1, len(h1_highs)) if h1_highs[i] > h1_highs[i - 1])
    hl_count = sum(1 for i in range(1, len(h1_lows)) if h1_lows[i] > h1_lows[i - 1])
    lh_count = sum(1 for i in range(1, len(h1_highs)) if h1_highs[i] < h1_highs[i - 1])
    ll_count = sum(1 for i in range(1, len(h1_lows)) if h1_lows[i] < h1_lows[i - 1])

    h1_struct_bull = (hh_count >= 2 and hl_count >= 2)
    h1_struct_bear = (lh_count >= 2 and ll_count >= 2)

    return {
        "market_structure": struct,
        "trend_maturity":   max(h1_up, h1_down),
        "h1_struct_bull":   h1_struct_bull,
        "h1_struct_bear":   h1_struct_bear,
        "atr_h1":           float(atr_h1_cur),
    }
