# app/src/trading/auto/autonomous_management.py

from __future__ import annotations

from src.core.numbers import safe_float
from src.trading.auto.state import AutoTradeState
from src.trading.execution.constants import (
    AUTONOMOUS_ACTION_EXIT,
    AUTONOMOUS_ACTION_HOLD,
    AUTONOMOUS_ACTION_PROTECT,
    AUTONOMOUS_ACTION_REDUCE,
    AUTONOMOUS_ACTION_WATCH,
    AUTONOMOUS_AGGRESSIVE_EXIT_CONFIDENCE_THRESHOLD,
    AUTONOMOUS_EXIT_CONFIDENCE_THRESHOLD,
    POSITION_EXIT_SIGNAL_EXIT,
    POSITION_EXIT_SIGNAL_HOLD,
    POSITION_EXIT_SIGNAL_REDUCE_OR_PROTECT,
    POSITION_EXIT_SIGNAL_WATCH,
    POSITION_PRESSURE_HIGH_LOSS,
    POSITION_PRESSURE_LOSS,
    POSITION_TREND_AGAINST,
    POSITION_SIDE_NONE,
)


class AutoAutonomousManagementMixin:
    # синхронизировать автономное управление открытой позицией
    def _sync_autonomous_trade_management(
        self,
        state: AutoTradeState,
    ) -> None:
        # Если позиции нет или она неполная, очищаем autonomous-state,
        # чтобы не осталось старого действия от прошлой позиции.
        if state.position_side == POSITION_SIDE_NONE or state.entry_price is None:
            state.autonomous_action = None
            state.autonomous_action_reason = None
            state.autonomous_action_confidence = None
            state.autonomous_protection_required = False
            state.autonomous_reduce_required = False
            state.autonomous_exit_required = False
            return

        exit_signal = str(
            state.position_exit_signal
            or POSITION_EXIT_SIGNAL_HOLD
        ).upper()
        exit_confidence = safe_float(state.position_exit_confidence) or 0.0
        position_pressure = str(state.position_pressure or "").upper()
        trend_alignment = str(state.position_trend_alignment or "").upper()

        action = AUTONOMOUS_ACTION_HOLD
        reason = "позиция удерживается"

        protect_required = False
        reduce_required = False
        exit_required = False

        if exit_signal == POSITION_EXIT_SIGNAL_WATCH:
            action = AUTONOMOUS_ACTION_WATCH
            reason = "позиция требует наблюдения"

        elif exit_signal == POSITION_EXIT_SIGNAL_REDUCE_OR_PROTECT:
            if position_pressure in {POSITION_PRESSURE_HIGH_LOSS, POSITION_PRESSURE_LOSS}:
                action = AUTONOMOUS_ACTION_REDUCE
                reduce_required = True
                reason = "позиция должна быть уменьшена"
            else:
                action = AUTONOMOUS_ACTION_PROTECT
                protect_required = True
                reason = "позиция требует защиты"

        elif exit_signal == POSITION_EXIT_SIGNAL_EXIT:
            if exit_confidence >= AUTONOMOUS_EXIT_CONFIDENCE_THRESHOLD:
                action = AUTONOMOUS_ACTION_EXIT
                exit_required = True
                reason = "позиция требует закрытия"
            else:
                action = AUTONOMOUS_ACTION_PROTECT
                protect_required = True
                reason = "позиция требует защиты перед возможным выходом"

        # Жёсткая эскалация: если и тренд, и momentum против позиции,
        # автономное управление должно требовать выход, а не частичную защиту.
        if (
            state.position_adverse_momentum
            and trend_alignment == POSITION_TREND_AGAINST
            and exit_confidence >= AUTONOMOUS_AGGRESSIVE_EXIT_CONFIDENCE_THRESHOLD
        ):
            action = AUTONOMOUS_ACTION_EXIT
            exit_required = True
            reduce_required = False
            protect_required = False
            reason = "рынок агрессивно движется против позиции"

        state.autonomous_action = action
        state.autonomous_action_reason = reason
        state.autonomous_action_confidence = exit_confidence
        state.autonomous_protection_required = protect_required
        state.autonomous_reduce_required = reduce_required
        state.autonomous_exit_required = exit_required