"""Realtime domain — HTTP routes."""
from __future__ import annotations

from uuid import UUID

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession

from src.core.database import get_db
from src.core.dependencies import require_active_billing_for_project_id
from src.domain.auth.models import User
from src.domain.auth.router import get_current_user
from src.domain.projects.repository import ProjectRepository
from src.domain.workspaces.repository import WorkspaceRepository
from src.domain.realtime.repository import (
    ProjectRealtimeChannelRepository,
    ProjectRealtimeConfigRepository,
)
from src.domain.realtime.schemas import (
    BroadcastRequest,
    ChannelResponse,
    CreateChannelRequest,
    RealtimeConfigResponse,
    RealtimeStatsResponse,
    UpdateChannelRequest,
    UpdateRealtimeConfigRequest,
)
from src.domain.realtime.service import RealtimeService
from src.integrations.cloud_control_client import CloudControlClient

router = APIRouter(
    prefix="/api/projects/{project_id}/realtime",
    tags=["realtime"],
)


def _get_service(db: AsyncSession = Depends(get_db)) -> RealtimeService:
    return RealtimeService(
        config_repo=ProjectRealtimeConfigRepository(db),
        channel_repo=ProjectRealtimeChannelRepository(db),
        cloud_client=CloudControlClient(),
    )


@router.get("/config", response_model=RealtimeConfigResponse)
async def get_realtime_config(
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: RealtimeService = Depends(_get_service),
) -> RealtimeConfigResponse:
    return await svc.get_or_create_config(project_id)


@router.patch("/config", response_model=RealtimeConfigResponse)
async def update_realtime_config(
    body: UpdateRealtimeConfigRequest,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
    svc: RealtimeService = Depends(_get_service),
) -> RealtimeConfigResponse:
    proj = await ProjectRepository(db).get_by_id(project_id)
    ws = await WorkspaceRepository(db).get_by_id(proj.workspace_id) if proj else None
    plan_slug = getattr(ws, "selected_plan_slug", None) if ws else None
    return await svc.update_config(project_id, body, plan_slug=plan_slug)


@router.get("/channels", response_model=list[ChannelResponse])
async def list_channels(
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: RealtimeService = Depends(_get_service),
) -> list[ChannelResponse]:
    return await svc.list_channels(project_id)


@router.post("/channels", response_model=ChannelResponse, status_code=201)
async def create_channel(
    body: CreateChannelRequest,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: RealtimeService = Depends(_get_service),
) -> ChannelResponse:
    return await svc.create_channel(project_id, body)


@router.patch("/channels/{name:path}", response_model=ChannelResponse)
async def update_channel(
    name: str,
    body: UpdateChannelRequest,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: RealtimeService = Depends(_get_service),
) -> ChannelResponse:
    return await svc.update_channel(project_id, name, body)


@router.delete("/channels/{name:path}", status_code=204, response_model=None)
async def delete_channel(
    name: str,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: RealtimeService = Depends(_get_service),
) -> None:
    await svc.delete_channel(project_id, name)


@router.get("/stats", response_model=RealtimeStatsResponse)
async def get_realtime_stats(
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: RealtimeService = Depends(_get_service),
) -> RealtimeStatsResponse:
    return await svc.get_stats(project_id)


@router.post("/broadcast", status_code=202, response_model=None)
async def broadcast(
    body: BroadcastRequest,
    project_id: UUID = Depends(require_active_billing_for_project_id),
    _: User = Depends(get_current_user),
    svc: RealtimeService = Depends(_get_service),
) -> None:
    await svc.broadcast(project_id, body)
