#!/usr/bin/env python3
from __future__ import annotations
import json
from pathlib import Path
from typing import Any

import config_manager


def _safe_upper(value: Any, default: str) -> str:
    text = str(value or default).strip().upper()
    return text or default


def _safe_float(value: Any, default: float) -> float:
    try:
        return float(value)
    except Exception:
        return float(default)


def load_latest_structure_snapshot() -> dict:
    app_dir = Path(config_manager.get_app_dir())
    structure_file = app_dir / "data" / "agent_signal_override.json"
    if not structure_file.exists():
        return {}
    try:
        data = json.loads(structure_file.read_text(encoding="utf-8"))
        return data if isinstance(data, dict) else {}
    except Exception:
        return {}


def _compute_execution_friction(window_lines: int = 2000) -> dict:
    app_dir = Path(config_manager.get_app_dir())
    log_files = sorted((app_dir / "logs").glob("gold_trader*.log"), key=lambda p: p.stat().st_mtime, reverse=True)
    if not log_files:
        return {
            "hold_count": 0,
            "open_count": 0,
            "blocked_count": 0,
            "soft_limit_count": 0,
            "review_reject_count": 0,
            "friction_ratio": 0.0,
        }
    try:
        lines = log_files[0].read_text(errors="ignore", encoding="utf-8").splitlines()[-window_lines:]
    except Exception:
        lines = []

    hold_count = 0
    open_count = 0
    blocked_count = 0
    soft_limit_count = 0
    review_reject_count = 0
    for ln in lines:
        if "Signal: HOLD" in ln:
            hold_count += 1
        if "Signal: OPEN" in ln:
            open_count += 1
        if "RiskManager BLOCKED" in ln:
            blocked_count += 1
        if "软挂单已注册" in ln:
            soft_limit_count += 1
        if "Review否决" in ln:
            review_reject_count += 1
    friction_ratio = round((blocked_count + review_reject_count) / max(1, open_count), 3)
    return {
        "hold_count": hold_count,
        "open_count": open_count,
        "blocked_count": blocked_count,
        "soft_limit_count": soft_limit_count,
        "review_reject_count": review_reject_count,
        "friction_ratio": friction_ratio,
    }


def build_market_adaptive_profile(snapshot: dict | None = None) -> dict:
    snap = snapshot if isinstance(snapshot, dict) else load_latest_structure_snapshot()
    market_structure = _safe_upper(snap.get("market_structure"), "UNCERTAIN")
    regime_subtype = _safe_upper(snap.get("regime_subtype"), "STRUCTURE_UNCLEAR")
    volatility_state = _safe_upper(snap.get("volatility_state"), "NORMAL")
    liquidity_state = _safe_upper(snap.get("liquidity_state"), "NORMAL")
    continuation_bias = _safe_upper(snap.get("continuation_bias"), "NEUTRAL")
    entry_timing_hint = _safe_upper(snap.get("entry_timing_hint"), "WAIT_CLEAR_SIGNAL")
    llm_confidence = round(_safe_float(snap.get("llm_confidence"), 0.55), 3)

    strategy_sync_mode = "BALANCED"
    learning_focus = "MIXED"
    evolution_risk_bias = "NEUTRAL"
    confidence_delta = 0.0
    defensive_offset_delta = 0.0
    trailing_stop_delta = 0.0

    if regime_subtype in {"FLAG_COMPRESSION", "NARROW_BOX"}:
        strategy_sync_mode = "COMPRESSION_PROBE"
        learning_focus = "BREAKOUT_REPLAY_PRIORITY"
        evolution_risk_bias = "DEFENSIVE"
        confidence_delta = 0.01
        defensive_offset_delta = 0.08
        trailing_stop_delta = 0.10
    elif regime_subtype in {"REPRICING_IMPULSE", "TREND_FIRST_PULLBACK"}:
        strategy_sync_mode = "FAST_FOLLOW"
        learning_focus = "IMPULSE_CONTINUATION_PRIORITY"
        evolution_risk_bias = "AGGRESSIVE"
        confidence_delta = -0.02
        defensive_offset_delta = -0.06
        trailing_stop_delta = -0.08
    elif regime_subtype in {"WIDE_BOX", "REVERSAL_SETUP"} or liquidity_state == "WHIPSAW":
        strategy_sync_mode = "MEAN_REVERSION_GUARD"
        learning_focus = "REVERSAL_FILTER_PRIORITY"
        evolution_risk_bias = "DEFENSIVE"
        confidence_delta = 0.02
        defensive_offset_delta = 0.10
        trailing_stop_delta = 0.15
    elif continuation_bias in {"BULLISH", "BEARISH"} and volatility_state in {"LOW", "NORMAL"}:
        strategy_sync_mode = "DRIFT_SYNC"
        learning_focus = "TREND_DRIFT_PRIORITY"
        evolution_risk_bias = "NEUTRAL"
        confidence_delta = -0.01
        defensive_offset_delta = -0.03
        trailing_stop_delta = -0.04

    if llm_confidence < 0.42:
        strategy_sync_mode = "UNCERTAINTY_PROTECT"
        learning_focus = "NOISE_REDUCTION_PRIORITY"
        evolution_risk_bias = "DEFENSIVE"
        confidence_delta = max(confidence_delta, 0.02)
        defensive_offset_delta = max(defensive_offset_delta, 0.08)
        trailing_stop_delta = max(trailing_stop_delta, 0.10)

    friction = _compute_execution_friction()
    if friction["open_count"] <= 1 and friction["blocked_count"] >= 8:
        strategy_sync_mode = "OPPORTUNITY_RECOVERY"
        learning_focus = "FILL_RATE_RECOVERY_PRIORITY"
        confidence_delta -= 0.03
        defensive_offset_delta -= 0.08
        trailing_stop_delta -= 0.05
    elif friction["friction_ratio"] >= 2.5:
        strategy_sync_mode = "FRICTION_REBALANCE"
        learning_focus = "BLOCK_RATIO_REDUCTION_PRIORITY"
        confidence_delta -= 0.02
        defensive_offset_delta -= 0.05
        trailing_stop_delta -= 0.03

    return {
        "market_structure": market_structure,
        "regime_subtype": regime_subtype,
        "volatility_state": volatility_state,
        "liquidity_state": liquidity_state,
        "continuation_bias": continuation_bias,
        "entry_timing_hint": entry_timing_hint,
        "llm_confidence": llm_confidence,
        "strategy_sync_mode": strategy_sync_mode,
        "learning_focus": learning_focus,
        "evolution_risk_bias": evolution_risk_bias,
        "confidence_delta": round(confidence_delta, 3),
        "defensive_offset_delta": round(defensive_offset_delta, 3),
        "trailing_stop_delta": round(trailing_stop_delta, 3),
        "execution_friction": friction,
    }
