"""
routers/chat_router.py
------------------------
Wraps mindscreen.ConversationManager (pure Python chatbot/scoring logic,
already unit-tested in the mindscreen package) with persistence and auth.

IMPORTANT IMPLEMENTATION NOTE: ConversationManager is a stateful in-memory
object. This build stage keeps active sessions in a simple in-process dict
(`_active_sessions`), which is fine for local development / a single-worker
deployment. For a production, multi-worker deployment, replace this with a
persistent session store (e.g. reconstruct state from the DB rows on each
request, or keep session affinity via Redis) — noted here explicitly rather
than silently shipping something that would break under horizontal scaling.
"""

from typing import Dict

from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from mindscreen.conversation_manager import ConversationManager
from mindscreen.models import Speaker as MSSpeaker

from .. import db_models, schemas
from ..auth import get_current_user
from ..database import get_db
from ..services.report_service import build_report_html, summarize_conversation

router = APIRouter(prefix="/chat", tags=["chat"])

# session_uuid -> ConversationManager instance (see module docstring)
_active_sessions: Dict[str, ConversationManager] = {}


@router.post("/start", response_model=schemas.ChatStartResponse)
def start_chat(
    db: Session = Depends(get_db), current_user: db_models.User = Depends(get_current_user)
):
    cm = ConversationManager(participant_id=current_user.participant_code)
    bot_message = cm.start()

    db_session = db_models.ChatSession(
        session_uuid=cm.state.session_id,
        user_id=current_user.id,
        stage=cm.state.stage.value,
    )
    db.add(db_session)
    db.commit()
    db.refresh(db_session)

    db.add(db_models.Message(session_id=db_session.id, speaker="bot", content=bot_message))
    db.commit()

    _active_sessions[cm.state.session_id] = cm
    return schemas.ChatStartResponse(
        session_uuid=cm.state.session_id, bot_message=bot_message, stage=cm.state.stage.value
    )


def _get_owned_db_session(
    session_uuid: str, db: Session, current_user: db_models.User
) -> db_models.ChatSession:
    db_session = (
        db.query(db_models.ChatSession)
        .filter(db_models.ChatSession.session_uuid == session_uuid)
        .first()
    )
    if not db_session or db_session.user_id != current_user.id:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Session not found.")
    return db_session


@router.post("/message", response_model=schemas.ChatMessageResponse)
def send_message(
    payload: schemas.ChatMessageRequest,
    db: Session = Depends(get_db),
    current_user: db_models.User = Depends(get_current_user),
):
    db_session = _get_owned_db_session(payload.session_uuid, db, current_user)

    cm = _active_sessions.get(payload.session_uuid)
    if cm is None:
        raise HTTPException(
            status_code=status.HTTP_410_GONE,
            detail="This session is no longer active in memory (e.g. server restarted). "
                   "Please start a new session.",
        )

    out = cm.handle_user_turn(payload.message)

    # Persist the user turn + bot reply for audit/dashboard purposes.
    db.add(db_models.Message(
        session_id=db_session.id, speaker="user", content=payload.message,
        nlp_features=cm.state.messages[-2].nlp_features if len(cm.state.messages) >= 2 else None,
    ))
    db.add(db_models.Message(session_id=db_session.id, speaker="bot", content=out["bot_message"]))
    db_session.stage = out["stage"].value
    db_session.safety_paused = cm.state.safety_paused

    is_complete = out["stage"].value == "complete"
    result_dict = None

    if out["result"] is not None:
        result = out["result"]
        result_dict = result.to_dict()

        # Persist questionnaire responses
        for instrument, responses in (
            ("PHQ9", cm.state.phq9_responses),
            ("GAD7", cm.state.gad7_responses),
            ("PSS10", cm.state.pss10_responses),
        ):
            for idx, value in enumerate(responses):
                db.add(db_models.QuestionnaireResponse(
                    session_id=db_session.id, instrument=instrument,
                    item_index=idx, response_value=value,
                ))

        db.add(db_models.AIPrediction(
            session_id=db_session.id,
            depression_score=result.depression.combined_score,
            depression_risk_level=result.depression.risk_level,
            anxiety_score=result.anxiety.combined_score,
            anxiety_risk_level=result.anxiety.risk_level,
            stress_score=result.stress.combined_score,
            stress_risk_level=result.stress.risk_level,
            overall_wellness_score=result.overall_wellness_score,
            confidence_score=result.confidence_score,
            ml_predicted_risk=(result.ml_signal or {}).get("predicted_risk"),
            explanation_json=result_dict,
        ))

        user_messages = [m.text for m in cm.state.messages if m.speaker == MSSpeaker.USER]
        nlp_summary = cm.analyzer.aggregate(cm._text_features_log)
        summary_text = summarize_conversation(user_messages, nlp_summary)
        report_html = build_report_html(
            participant_code=current_user.participant_code,
            session_uuid=payload.session_uuid,
            result_dict=result_dict,
            conversation_summary=summary_text,
        )
        db.add(db_models.Report(session_id=db_session.id, report_html=report_html))

        db_session.completed_at = cm.state.completed_at
        _active_sessions.pop(payload.session_uuid, None)

    db.commit()

    return schemas.ChatMessageResponse(
        bot_message=out["bot_message"], stage=out["stage"].value,
        safety_triggered=out["safety_triggered"], is_complete=is_complete, result=result_dict,
    )


@router.get("/history/{session_uuid}", response_model=schemas.SessionHistoryResponse)
def get_history(
    session_uuid: str, db: Session = Depends(get_db),
    current_user: db_models.User = Depends(get_current_user),
):
    db_session = _get_owned_db_session(session_uuid, db, current_user)
    return schemas.SessionHistoryResponse(
        session_uuid=db_session.session_uuid,
        stage=db_session.stage,
        started_at=db_session.started_at,
        completed_at=db_session.completed_at,
        messages=db_session.messages,
    )


@router.get("/sessions")
def list_my_sessions(
    db: Session = Depends(get_db), current_user: db_models.User = Depends(get_current_user)
):
    sessions = (
        db.query(db_models.ChatSession)
        .filter(db_models.ChatSession.user_id == current_user.id)
        .order_by(db_models.ChatSession.started_at.desc())
        .all()
    )
    return [
        {
            "session_uuid": s.session_uuid, "stage": s.stage,
            "started_at": s.started_at, "completed_at": s.completed_at,
        }
        for s in sessions
    ]
