"""
Session Manager

Lists active call/conference sessions and manages session metadata.
REST API: GET /api/v1/sessions, PUT /api/v1/sessions/{linkedId}/meta
"""

from __future__ import annotations

from datetime import datetime
from typing import Any
from urllib.parse import quote

from dvgateway.transport.http_client import HttpClient
from dvgateway.types import CallSession, Logger, StreamDir


class SessionManager:
    """Manages active call and conference sessions."""

    def __init__(self, http: HttpClient, logger: Logger) -> None:
        self._http = http
        self._logger = logger

    async def list_sessions(self) -> list[CallSession]:
        """List all currently active call sessions."""
        response = await self._http.get("/api/v1/sessions")
        if response.status != 200:
            raise RuntimeError(f"Failed to list sessions: HTTP {response.status}")
        sessions = response.data.get("sessions", []) if isinstance(response.data, dict) else []
        return [self._normalize_session(s) for s in sessions]

    async def list_sessions_by_tenant(self, tenant_id: str) -> list[CallSession]:
        """List active call sessions filtered by tenant ID."""
        response = await self._http.get(f"/api/v1/sessions?tenantId={quote(tenant_id)}")
        if response.status != 200:
            raise RuntimeError(f"Failed to list sessions by tenant: HTTP {response.status}")
        sessions = response.data.get("sessions", []) if isinstance(response.data, dict) else []
        return [self._normalize_session(s) for s in sessions]

    async def update_metadata(self, linked_id: str, meta: dict[str, str]) -> None:
        """Update metadata key-value pairs on a session."""
        response = await self._http.put(
            f"/api/v1/sessions/{quote(linked_id)}/meta",
            body={"metadata": meta},
        )
        if response.status not in (200, 204):
            raise RuntimeError(f"Failed to update session metadata: HTTP {response.status}")
        self._logger.debug({"linked_id": linked_id, "keys": list(meta.keys())}, "Session metadata updated")

    @staticmethod
    def _normalize_session(raw: dict[str, Any]) -> CallSession:
        started_at_str = raw.get("startedAt")
        started_at = datetime.fromisoformat(started_at_str) if started_at_str else datetime.now()
        return CallSession(
            linked_id=raw.get("linkedId", ""),
            conf_id=raw.get("confId"),
            dir=raw.get("dir", "both"),
            caller=raw.get("caller"),
            caller_name=raw.get("callerName"),
            callee=raw.get("callee"),
            did=raw.get("did"),
            call_id=raw.get("callid"),
            agent_number=raw.get("agentNumber"),
            started_at=started_at,
            stream_url=raw.get("streamUrl", ""),
            tenant_id=raw.get("tenantId"),
            custom_value_1=raw.get("customValue1"),
            custom_value_2=raw.get("customValue2"),
            custom_value_3=raw.get("customValue3"),
            metadata=raw.get("metadata"),
        )
