from __future__ import annotations

import json

from fastapi import FastAPI
from sqlalchemy import select

from services.shared.core import new_id, utc_now_iso
from services.shared.db import get_session
from services.shared.models import HealthResponse, WebchatMessageIn, WebchatMessageOut
from services.shared.sql_init import init_sql_schema
from services.shared.sql_models import Interaction, InteractionTimeline, WebchatMessageRow

app = FastAPI(title="webchat-adapter-service", version="2.0.0")

init_sql_schema()


def _to_out(row: WebchatMessageRow) -> WebchatMessageOut:
    return WebchatMessageOut(
        message_id=row.message_id,
        session_id=row.session_id,
        text=row.text,
        visitor_name=row.visitor_name,
        customer_external_id=row.customer_external_id,
        queue_id=row.queue_id,
        priority=row.priority,
        payload=json.loads(row.payload_json or "{}"),
        interaction_id=row.interaction_id,
        created_at=row.created_at,
    )


def _interaction_subject(payload: WebchatMessageIn) -> str:
    subject = str(payload.payload.get("subject", "")).strip()
    if subject:
        return subject[:120]
    text = payload.text.strip()
    if len(text) <= 120:
        return text
    return f"{text[:117]}..."


def _create_interaction(session, payload: WebchatMessageIn, created_at: str) -> str:
    interaction_id = new_id("int")
    session.add(
        Interaction(
            interaction_id=interaction_id,
            channel="webchat",
            subject=_interaction_subject(payload),
            customer_id=payload.customer_external_id,
            queue_id=payload.queue_id or "q_webchat",
            priority=payload.priority,
            status="new",
            assigned_to=None,
            created_at=created_at,
            updated_at=created_at,
        )
    )
    session.add(
        InteractionTimeline(
            interaction_id=interaction_id,
            timestamp=created_at,
            action="interaction.created",
            metadata_json=json.dumps({"channel": "webchat"}, ensure_ascii=False),
        )
    )
    session.add(
        InteractionTimeline(
            interaction_id=interaction_id,
            timestamp=created_at,
            action="webchat.message_received",
            metadata_json=json.dumps({"session_id": payload.session_id}, ensure_ascii=False),
        )
    )
    return interaction_id


@app.get("/health", response_model=HealthResponse)
def health() -> HealthResponse:
    return HealthResponse(status="ok", service="webchat-adapter-service", version="v2")


@app.post("/integrations/webchat/messages", response_model=WebchatMessageOut)
def create_message(payload: WebchatMessageIn) -> WebchatMessageOut:
    session = get_session()
    try:
        created_at = utc_now_iso()
        interaction_id = _create_interaction(session, payload, created_at)
        row = WebchatMessageRow(
            message_id=new_id("wcm"),
            session_id=payload.session_id,
            text=payload.text,
            visitor_name=payload.visitor_name,
            customer_external_id=payload.customer_external_id,
            interaction_id=interaction_id,
            queue_id=payload.queue_id or "q_webchat",
            priority=payload.priority,
            payload_json=json.dumps(payload.payload, ensure_ascii=False),
            created_at=created_at,
        )
        session.add(row)
        session.commit()
        session.refresh(row)
        return _to_out(row)
    finally:
        session.close()


@app.get("/integrations/webchat/messages", response_model=list[WebchatMessageOut])
def list_messages(session_id: str | None = None, limit: int = 100) -> list[WebchatMessageOut]:
    session = get_session()
    try:
        stmt = select(WebchatMessageRow).order_by(WebchatMessageRow.id.desc())
        if session_id:
            stmt = stmt.where(WebchatMessageRow.session_id == session_id)
        rows = session.execute(stmt.limit(max(limit, 1))).scalars().all()
        return [_to_out(row) for row in reversed(rows)]
    finally:
        session.close()
