from __future__ import annotations

from datetime import datetime
from typing import Any


def normalize_compile_target(value: str = "", *, base_engine: str = "") -> str:
    target = str(value or "").strip().lower()
    if target in {"template", "plugin"}:
        return target
    if str(base_engine or "").strip().lower() == "plugin":
        return "plugin"
    return "template"


def build_strategy_spec(
    *,
    name: str,
    document: str,
    optimized: dict[str, Any] | None = None,
    compile_target: str = "",
    strategy_id: str = "",
) -> dict[str, Any]:
    optimized_payload = optimized if isinstance(optimized, dict) else {}
    params = (
        optimized_payload.get("params", {})
        if isinstance(optimized_payload.get("params", {}), dict)
        else {}
    )
    risk_constraints = (
        optimized_payload.get("risk_constraints", {})
        if isinstance(optimized_payload.get("risk_constraints", {}), dict)
        else {}
    )
    base_engine = str(
        optimized_payload.get("base_engine") or "ema_macd"
    ).strip() or "ema_macd"
    target = normalize_compile_target(compile_target, base_engine=base_engine)
    timeframe = str(params.get("timeframe", "M5") or "M5").strip() or "M5"
    thesis = str(
        optimized_payload.get("market_hypothesis")
        or document[:180]
        or name
    ).strip()
    entry_rule = str(
        optimized_payload.get("entry_rule")
        or "signal_confirmed_and_spread_safe"
    ).strip()
    exit_rule = str(
        optimized_payload.get("exit_rule")
        or "exit_optimizer_or_sl_tp"
    ).strip()
    return {
        "spec_version": 1,
        "strategy_id": str(strategy_id or "").strip(),
        "name": str(name or "").strip(),
        "compile_target": target,
        "base_engine": base_engine,
        "market": {
            "symbol": "XAUUSD",
            "timeframes": [timeframe],
            "regimes": [str(base_engine).strip()],
        },
        "thesis": thesis,
        "entry": {
            "rule": entry_rule,
            "params": dict(params),
        },
        "exit": {
            "rule": exit_rule,
            "params": {
                key: value
                for key, value in params.items()
                if key in {"sl_multiplier", "tp_multiplier"}
            },
        },
        "risk": dict(risk_constraints),
        "source": {
            "document": str(document or ""),
            "document_summary": str(document or "")[:220],
        },
        "metadata": {
            "strategy_name": str(
                optimized_payload.get("strategy_name")
                or name
                or ""
            ).strip(),
        },
    }


def build_validation_report(
    *,
    evaluation: dict[str, Any] | None = None,
    optimized: dict[str, Any] | None = None,
) -> dict[str, Any]:
    evaluation_payload = evaluation if isinstance(evaluation, dict) else {}
    optimized_payload = optimized if isinstance(optimized, dict) else {}
    risk_constraints = (
        optimized_payload.get("risk_constraints", {})
        if isinstance(optimized_payload.get("risk_constraints", {}), dict)
        else {}
    )
    verdict = str(evaluation_payload.get("verdict", "needs_improve") or "needs_improve").strip().lower()
    return {
        "schema": "pass",
        "risk": "pass" if bool(risk_constraints) else "needs_review",
        "llm_verdict": verdict,
        "status": "pass" if verdict == "pass" else "needs_improve",
        "score": (
            evaluation_payload.get("score", {})
            if isinstance(evaluation_payload.get("score", {}), dict)
            else {}
        ),
        "risk_exposure": str(
            evaluation_payload.get("riskExposure", "medium") or "medium"
        ),
        "advice": str(evaluation_payload.get("advice", "") or ""),
        "updated_at": datetime.now().astimezone().isoformat(timespec="seconds"),
    }


def build_promotion_state(
    *,
    lifecycle_stage: str,
    review_status: str = "pending",
    promoted_at: str = "",
) -> dict[str, Any]:
    return {
        "stage": str(lifecycle_stage or "draft"),
        "review_status": str(review_status or "pending"),
        "promoted_at": str(promoted_at or ""),
    }
