"""
Onboarding wizard — guides first-time users through setup steps.

Steps:
  1. Accept Risk Disclosure
  2. Activate License
  3. Connect MT5 / Broker
  4. Configure Risk Profile
  5. Start Paper Trading → Graduate to Live

State is persisted so users can resume where they left off.
"""
from __future__ import annotations

import json
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

ONBOARDING_STATE = Path(__file__).resolve().parent.parent.parent / "data" / "onboarding" / "state.json"

STEPS = [
    {"id": "risk_disclosure", "label": "Accept Risk Disclosure", "order": 1},
    {"id": "license", "label": "Activate License", "order": 2},
    {"id": "mt5_connect", "label": "Connect MT5 Terminal", "order": 3},
    {"id": "risk_profile", "label": "Configure Risk Profile", "order": 4},
    {"id": "paper_trade", "label": "Paper Trading Validation", "order": 5},
    {"id": "go_live", "label": "Ready for Live Trading", "order": 6},
]


def _load_state() -> dict[str, Any]:
    if ONBOARDING_STATE.exists():
        try:
            return json.loads(ONBOARDING_STATE.read_text(encoding="utf-8"))
        except (json.JSONDecodeError, OSError):
            pass
    return {"steps": {}, "started_at": None, "completed_at": None}


def _save_state(state: dict[str, Any]) -> None:
    ONBOARDING_STATE.parent.mkdir(parents=True, exist_ok=True)
    ONBOARDING_STATE.write_text(json.dumps(state, ensure_ascii=False, indent=2), encoding="utf-8")


def start_onboarding() -> dict[str, Any]:
    state = _load_state()
    if not state.get("started_at"):
        state["started_at"] = datetime.now(timezone.utc).isoformat()
    _save_state(state)
    return get_progress()


def get_progress() -> dict[str, Any]:
    state = _load_state()
    steps_status = []
    completed_count = 0
    for step in STEPS:
        s = state.get("steps", {}).get(step["id"], {})
        done = bool(s.get("completed"))
        if done:
            completed_count += 1
        steps_status.append({
            **step,
            "completed": done,
            "completed_at": s.get("completed_at", ""),
            "data": s.get("data", {}),
        })

    return {
        "steps": steps_status,
        "completed": completed_count,
        "total": len(STEPS),
        "pct": round(completed_count / len(STEPS) * 100),
        "started_at": state.get("started_at"),
        "finished": bool(state.get("completed_at")),
        "ready_for_live": completed_count >= 5,  # 0-4 must be done
    }


def complete_step(step_id: str, data: dict[str, Any] | None = None) -> dict[str, Any]:
    """Mark an onboarding step as completed."""
    valid_ids = {s["id"] for s in STEPS}
    if step_id not in valid_ids:
        return {"ok": False, "error": f"Invalid step: {step_id}"}

    state = _load_state()
    state.setdefault("steps", {})
    state["steps"][step_id] = {
        "completed": True,
        "completed_at": datetime.now(timezone.utc).isoformat(),
        "data": data or {},
    }

    # Check if all steps done
    all_done = all(
        state["steps"].get(s["id"], {}).get("completed")
        for s in STEPS
    )
    if all_done:
        state["completed_at"] = datetime.now(timezone.utc).isoformat()

    _save_state(state)
    return get_progress()


def reset_onboarding() -> None:
    """Reset onboarding progress (for re-installation scenarios)."""
    if ONBOARDING_STATE.exists():
        ONBOARDING_STATE.unlink()


def is_onboarding_complete() -> bool:
    progress = get_progress()
    return progress["ready_for_live"]


# ─── Risk Profile Configuration ────────────────────────────────────

def save_risk_profile(profile: dict[str, Any]) -> dict[str, Any]:
    """Save user's risk profile settings."""
    return complete_step("risk_profile", {
        "max_position_size": float(profile.get("max_position_size", 0.05)),
        "max_daily_loss_pct": float(profile.get("max_daily_loss_pct", 2.0)),
        "max_consecutive_losses": int(profile.get("max_consecutive_losses", 3)),
        "risk_per_trade_pct": float(profile.get("risk_per_trade_pct", 1.0)),
        "experience_level": str(profile.get("experience_level", "beginner")),
        "trading_style": str(profile.get("trading_style", "conservative")),
    })
