# src/data/indicators.py
"""
Indicadores técnicos calculados a partir de OHLCV.

Este módulo actúa como una capa de feature engineering
reutilizable por estrategias, filtros y ML.
"""

import pandas as pd
import pandas_ta as ta
from ..utils.logger import log


def add_adx(
    df: pd.DataFrame,
    length: int = 14,
    column_name: str = "adx",
) -> pd.DataFrame:
    """
    Añade el indicador ADX al DataFrame.

    - Nunca lanza excepción por falta de datos
    - Nunca devuelve None
    - Si no hay datos suficientes, rellena con NaN
    """
    required_cols = {"high", "low", "close"}
    if not required_cols.issubset(df.columns):
        raise ValueError(f"ADX requiere columnas: {required_cols}")

    # Asegura que la columna existe aunque no se pueda calcular aún
    if column_name not in df.columns:
        df[column_name] = pd.NA

    # No hay datos suficientes → salir limpio
    if len(df) < length + 1:
        log.debug(
            f"ADX no calculado (datos insuficientes: {len(df)}/{length})"
        )
        return df

    adx_df = ta.adx(
        high=df["high"],
        low=df["low"],
        close=df["close"],
        length=length,
    )

    # pandas_ta puede devolver None si no puede calcular
    if adx_df is None:
        log.debug("ADX no calculado (pandas_ta devolvió None)")
        return df

    adx_col = f"ADX_{length}"

    if adx_col not in adx_df.columns:
        log.debug(
            f"ADX no calculado (columna '{adx_col}' no presente)"
        )
        return df

    df[column_name] = adx_df[adx_col]

    log.debug(f"ADX añadido (length={length}) → columna '{column_name}'")
    return df
