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, EmailStr, Field, HttpUrl

from template_project.application.user.entity import UserId
from template_project.application.user.profile.interactors.get_profile import GetProfileInteractor
from template_project.application.user.profile.interactors.patch_profile import (
    PatchProfileInteractor,
    PatchProfileRequest,
)

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


class GetProfileResponse(BaseModel):
    id: UserId = Field(..., description="User ID")
    email: str | None = Field(None, description="User email address")
    display_name: str | None = Field(None, description="User display name")
    first_name: str | None = Field(None, description="User first name")
    last_name: str | None = Field(None, description="User last name")
    avatar_url: str | None = Field(None, description="URL to user avatar")
    phone: str | None = Field(None, description="User phone number")

    model_config = {
        "json_schema_extra": {
            "example": {
                "id": "01234567-89ab-cdef-0123-456789abcdef",
                "email": "user@example.com",
                "display_name": "John Doe",
                "first_name": "John",
                "last_name": "Doe",
                "avatar_url": "https://example.com/avatar.jpg",
                "phone": "+1234567890",
            }
        }
    }


@router.get(
    "/profile",
    summary="Get user profile",
    description="Retrieve the current authenticated user's profile information",
    responses={
        200: {"description": "Profile retrieved successfully", "model": GetProfileResponse},
        401: {"description": "Unauthorized - invalid or missing token"},
        404: {"description": "Profile not found"},
    },
)
async def get_profile(
    interactor: FromDishka[GetProfileInteractor],
) -> GetProfileResponse:
    response = await interactor.execute()
    if not response:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Profile not found")
    return GetProfileResponse(
        id=response.id,
        email=response.email,
        display_name=response.display_name,
        first_name=response.first_name,
        last_name=response.last_name,
        avatar_url=response.avatar_url,
        phone=response.phone,
    )


class PatchProfileRequestModel(BaseModel):
    email: EmailStr | None = Field(None, description="User email address", examples=["user@example.com"])
    display_name: str | None = Field(None, max_length=100, description="User display name", examples=["John Doe"])
    first_name: str | None = Field(None, max_length=50, description="User first name", examples=["John"])
    last_name: str | None = Field(None, max_length=50, description="User last name", examples=["Doe"])
    avatar_url: HttpUrl | None = Field(
        None, description="URL to user avatar", examples=["https://example.com/avatar.jpg"]
    )
    phone: str | None = Field(None, max_length=20, description="User phone number", examples=["+1234567890"])

    model_config = {
        "json_schema_extra": {
            "example": {
                "email": "user@example.com",
                "display_name": "John Doe",
                "first_name": "John",
                "last_name": "Doe",
                "avatar_url": "https://example.com/avatar.jpg",
                "phone": "+1234567890",
            }
        }
    }


class PatchProfileResponse(BaseModel):
    id: UserId = Field(..., description="User ID")
    email: str | None = Field(None, description="User email address")
    display_name: str | None = Field(None, description="User display name")
    first_name: str | None = Field(None, description="User first name")
    last_name: str | None = Field(None, description="User last name")
    avatar_url: str | None = Field(None, description="URL to user avatar")
    phone: str | None = Field(None, description="User phone number")

    model_config = {
        "json_schema_extra": {
            "example": {
                "id": "01234567-89ab-cdef-0123-456789abcdef",
                "email": "user@example.com",
                "display_name": "John Doe",
                "first_name": "John",
                "last_name": "Doe",
                "avatar_url": "https://example.com/avatar.jpg",
                "phone": "+1234567890",
            }
        }
    }


@router.patch(
    "/profile",
    summary="Update user profile",
    description="Update the current authenticated user's profile information. All fields are optional.",
    responses={
        200: {"description": "Profile updated successfully", "model": PatchProfileResponse},
        401: {"description": "Unauthorized - invalid or missing token"},
    },
)
async def patch_profile(
    request: PatchProfileRequestModel,
    interactor: FromDishka[PatchProfileInteractor],
) -> PatchProfileResponse:
    patch_request = PatchProfileRequest(
        email=request.email,
        display_name=request.display_name,
        first_name=request.first_name,
        last_name=request.last_name,
        avatar_url=str(request.avatar_url) if request.avatar_url else None,
        phone=request.phone,
    )
    response = await interactor.execute(patch_request)
    return PatchProfileResponse(
        id=response.id,
        email=response.email,
        display_name=response.display_name,
        first_name=response.first_name,
        last_name=response.last_name,
        avatar_url=response.avatar_url,
        phone=response.phone,
    )
