from dishka import FromDishka
from dishka.integrations.fastapi import DishkaRoute
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import HTTPBearer
from pydantic import BaseModel, Field

from template_project.application.notification_device.errors import NotificationDeviceNotFoundError
from template_project.application.notification_device.interactors.register_device import (
    RegisterNotificationDeviceInteractor,
    RegisterNotificationDeviceRequest,
)
from template_project.application.notification_device.interactors.send_notification import (
    NotificationInteractor,
    SendNotificationRequest,
)

security = HTTPBearer()
router = APIRouter(route_class=DishkaRoute, tags=["Notifications"], dependencies=[Depends(security)])


class SendNotificationRequestModel(BaseModel):
    title: str = Field(..., min_length=1, max_length=100, description="Notification title", examples=["New Message"])
    body: str = Field(
        ..., min_length=1, max_length=500, description="Notification body text", examples=["You have a new message"]
    )

    model_config = {"json_schema_extra": {"example": {"title": "New Message", "body": "You have a new message"}}}


class RegisterNotificationDeviceRequestModel(BaseModel):
    device_id: str = Field(
        ...,
        min_length=1,
        max_length=200,
        description="Device ID for push notifications (FCM token)",
        examples=["fcm_token_123456789"],
    )

    model_config = {"json_schema_extra": {"example": {"device_id": "fcm_token_123456789"}}}


@router.post(
    "/notifications/send",
    summary="Send notification",
    description="Send a push notification to the current user's registered device",
    responses={
        200: {"description": "Notification sent successfully"},
        401: {"description": "Unauthorized - invalid or missing token"},
        404: {"description": "Notification device not found - user needs to register device first"},
    },
)
async def send_notification(
    request: SendNotificationRequestModel,
    interactor: FromDishka[NotificationInteractor],
) -> None:
    try:
        notification_request = SendNotificationRequest(title=request.title, body=request.body)
        await interactor.send_notification(notification_request)
    except NotificationDeviceNotFoundError as error:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Notification device not found") from error


@router.post(
    "/notifications/register_device",
    summary="Register notification device",
    description="Register a device ID (FCM token) for push notifications for the current user",
    responses={
        200: {"description": "Device registered successfully"},
        401: {"description": "Unauthorized - invalid or missing token"},
    },
)
async def register_notification_device(
    request: RegisterNotificationDeviceRequestModel,
    interactor: FromDishka[RegisterNotificationDeviceInteractor],
) -> None:
    register_request = RegisterNotificationDeviceRequest(device_id=request.device_id)
    await interactor.execute(register_request)
