"""System Operations, Kill Switch & Mode Governance Endpoints."""
from __future__ import annotations

import uuid
from typing import Any

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel

from backend.app.alerts.engine import alert_engine
from backend.app.api.v1.auth import get_current_user
from backend.app.config.settings import TradingMode, settings
from backend.app.database.session import db_manager
from backend.app.risk.kill_switch import kill_switch

router = APIRouter(prefix="/system", tags=["System Operations"])


class KillSwitchTriggerRequest(BaseModel):
    reason: str


class ModeChangeRequest(BaseModel):
    new_mode: str
    confirmation_phrase: str


@router.get("/kill-switch")
async def get_kill_switch_state() -> dict[str, Any]:
    """Retrieve persistent emergency kill switch state."""
    return kill_switch.get_details()


@router.post("/kill-switch/trigger")
async def trigger_kill_switch_endpoint(
    req: KillSwitchTriggerRequest,
    user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Trip emergency kill switch immediately."""
    kill_switch.trigger(reason=req.reason, triggered_by=user.get("sub", "OPERATOR"))
    self_log_audit(user.get("sub"), "KILL_SWITCH_TRIGGERED", "SYSTEM", "KILL_SWITCH", {"reason": req.reason})
    return {"success": True, "message": "Emergency Kill Switch engaged successfully."}


@router.post("/kill-switch/reset")
async def reset_kill_switch_endpoint(
    user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Reset emergency kill switch (requires admin role)."""
    if user.get("role") != "admin":
        raise HTTPException(status_code=403, detail="Administrator credentials required to reset Kill Switch.")
    kill_switch.reset(reset_by=user.get("sub", "ADMIN"))
    self_log_audit(user.get("sub"), "KILL_SWITCH_RESET", "SYSTEM", "KILL_SWITCH", {})
    return {"success": True, "message": "Emergency Kill Switch disengaged."}


@router.post("/mode")
async def change_trading_mode(
    req: ModeChangeRequest,
    user: dict[str, Any] = Depends(get_current_user),
) -> dict[str, Any]:
    """Change operational trading mode with strict validation."""
    if user.get("role") != "admin":
        raise HTTPException(status_code=403, detail="Administrator privileges required to change trading mode.")

    target_mode = req.new_mode.upper()
    valid_modes = [m.value for m in TradingMode]
    if target_mode not in valid_modes:
        raise HTTPException(status_code=400, detail=f"Invalid trading mode: {target_mode}. Must be one of {valid_modes}.")

    # Special protection for LIVE mode
    if target_mode == "LIVE":
        if req.confirmation_phrase != "I CONFIRM AUTHORIZATION OF LIVE CRYPTO TRADING":
            raise HTTPException(
                status_code=400,
                detail="Live trading requires exact confirmation phrase: 'I CONFIRM AUTHORIZATION OF LIVE CRYPTO TRADING'",
            )
        if not settings.ENABLE_LIVE_TRADING:
            raise HTTPException(
                status_code=403,
                detail="Live execution is hard-locked in environment (ENABLE_LIVE_TRADING=False).",
            )
        if not settings.BYBIT_LIVE_API_KEY or not settings.BYBIT_LIVE_API_SECRET:
            raise HTTPException(
                status_code=400,
                detail="Live Bybit API credentials missing in environment.",
            )

    settings.TRADING_MODE = TradingMode(target_mode)
    self_log_audit(user.get("sub"), "MODE_CHANGED", "SYSTEM", "TRADING_MODE", {"new_mode": target_mode})
    return {"success": True, "active_mode": target_mode}


@router.get("/audit-logs")
async def get_audit_logs() -> list[dict[str, Any]]:
    """Retrieve immutable security and operational audit trail."""
    return db_manager.execute_read_all("SELECT * FROM audit_logs ORDER BY timestamp DESC LIMIT 100")


@router.get("/alerts")
async def get_alerts() -> list[dict[str, Any]]:
    """Retrieve recent system alert events."""
    return alert_engine.get_recent()


def self_log_audit(user_id: Any, action: str, entity_type: str, entity_id: str, details: dict[str, Any]) -> None:
    import json
    now = db_manager.execute_read_one("SELECT datetime('now') as now")["now"]
    db_manager.execute_write(
        "INSERT INTO audit_logs (id, user_id, action, entity_type, entity_id, details_json, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?)",
        (str(uuid.uuid4()), str(user_id or "ANONYMOUS"), action, entity_type, entity_id, json.dumps(details), now),
    )
