"""
Impact Monitor — instrument impact evaluation for market events and news.
Prefix: /api/impact
"""
import logging
from typing import Any, Dict, List, Optional

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

logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/impact", tags=["impact"])


# ── Schemas ───────────────────────────────────────────────────────────────────

class ImpactAdjustment(BaseModel):
    adjusted_score: float
    adjusted_direction: str
    override_rationale: str = ""


class CategoryUpdate(BaseModel):
    type: str
    sub_type: str = ""
    description: str = ""
    default_impacts: List[Dict[str, Any]] = []


# ── Categories ────────────────────────────────────────────────────────────────

@router.get("/categories")
def list_categories() -> List[Dict[str, Any]]:
    from services.database import get_all_event_categories
    import json
    cats = get_all_event_categories()
    for c in cats:
        try:
            c["default_impacts"] = json.loads(c.get("default_impacts") or "[]")
        except Exception:
            c["default_impacts"] = []
    return cats


@router.delete("/categories/{name}")
def delete_category(name: str) -> Dict[str, Any]:
    from services.database import delete_event_category
    ok = delete_event_category(name)
    if not ok:
        raise HTTPException(404, f"Category '{name}' not found")
    return {"status": "deleted", "name": name}


@router.put("/categories/{name}")
def update_category(name: str, body: CategoryUpdate) -> Dict[str, Any]:
    from services.database import upsert_event_category
    import json
    cat_id = upsert_event_category({
        "name": name,
        "type": body.type,
        "sub_type": body.sub_type,
        "description": body.description,
        "default_impacts": json.dumps(body.default_impacts),
    })
    return {"id": cat_id, "name": name, "status": "updated"}


# ── Evaluate ──────────────────────────────────────────────────────────────────

@router.post("/evaluate/event/{event_id}")
def evaluate_event(
    event_id: int,
    force: bool = Query(False, description="Re-evaluate even if already done"),
) -> Dict[str, Any]:
    """Trigger AI impact evaluation for a market event."""
    from services.impact_service import evaluate_event_impacts
    try:
        result = evaluate_event_impacts(event_id, force=force)
        if "error" in result:
            raise HTTPException(400, result["error"])
        return result
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"[impact] evaluate_event {event_id} failed: {e}")
        raise HTTPException(500, str(e))


@router.post("/evaluate/bulk")
def evaluate_bulk(
    event_ids: List[int],
    force: bool = Query(False),
) -> Dict[str, Any]:
    """Evaluate multiple events sequentially."""
    from services.impact_service import evaluate_event_impacts
    results = []
    errors = []
    for eid in event_ids[:20]:  # cap at 20 per call
        try:
            r = evaluate_event_impacts(eid, force=force)
            if "error" not in r:
                results.append({"event_id": eid, "n_instruments": r.get("n_instruments", 0)})
            else:
                errors.append({"event_id": eid, "error": r["error"]})
        except Exception as e:
            errors.append({"event_id": eid, "error": str(e)})
    return {"evaluated": len(results), "errors": len(errors), "results": results, "error_details": errors}


# ── Monitor ───────────────────────────────────────────────────────────────────

@router.get("/monitor")
def get_monitor(
    days: int = Query(7,  ge=1, le=90,  description="Fenêtre temporelle en jours"),
    min_score: float = Query(0.3, ge=0.0, le=1.0, description="Score minimum d'impact"),
) -> Dict[str, Any]:
    """Weekly impact monitor — evaluated events with instrument scores."""
    from services.impact_service import get_impact_monitor_data
    try:
        return get_impact_monitor_data(days=days, min_score=min_score)
    except Exception as e:
        logger.error(f"[impact] monitor failed: {e}")
        raise HTTPException(500, str(e))


@router.get("/event/{event_id}")
def get_event_impacts(event_id: int) -> Dict[str, Any]:
    """Get stored impacts for a specific event."""
    from services.database import get_impacts_for_source, get_all_market_events
    impacts = get_impacts_for_source("event", event_id)
    events = get_all_market_events()
    event = next((e for e in events if e["id"] == event_id), None)
    return {
        "event_id": event_id,
        "event": event,
        "impacts": impacts,
        "evaluated": len(impacts) > 0,
    }


# ── Adjust ────────────────────────────────────────────────────────────────────

@router.put("/adjust/{impact_id}")
def adjust_impact(impact_id: int, body: ImpactAdjustment) -> Dict[str, Any]:
    """Manually override an AI-estimated impact score/direction."""
    from services.database import update_impact_adjustment
    ok = update_impact_adjustment(
        impact_id,
        body.adjusted_score,
        body.adjusted_direction,
        body.override_rationale,
    )
    if not ok:
        raise HTTPException(404, f"Impact {impact_id} not found")
    return {"id": impact_id, "status": "adjusted"}


# ── Bootstrap ─────────────────────────────────────────────────────────────────

@router.post("/bootstrap-categories")
def bootstrap_categories(force: bool = False) -> Dict[str, Any]:
    """Seed default impact categories."""
    from services.impact_categories_bootstrap import bootstrap_impact_categories
    return bootstrap_impact_categories(force=force)
