from typing import Annotated
from uuid import UUID

from fastapi import APIRouter, Depends, HTTPException, Path, status
from psycopg import Connection
from pydantic import BaseModel, Field
from src.__types.error_responses import INTERNAL_ERROR_DETAIL, NOT_FOUND_DETAIL, ErrorResponse
from src.__types.errors import ResourceNotFoundError
from src.logger import logger
from src.routers.management.connection import get_connection_without_tenant_scope
from src.tracer import tracer
from src.usecases.tenant_auth_info_usecase import TenantAuthInfoUseCase

router = APIRouter(
    prefix="/tenants",
    tags=["その他"],  # NOTE: 認証前のテナント特定用エンドポイントなので、管理系の他のエンドポイントとはタグを分ける
)


class GetAuthInfoResponse(BaseModel):
    tenant_id: UUID = Field(..., description="テナントID")
    application_client_id: str = Field(..., description="ユーザー認証で利用するアプリケーションクライアントID")

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "tenant_id": "123e4567-e89b-12d3-a456-426614174000",
                    "application_client_id": "example_client_id",
                },
            ],
        },
    }


@router.get(
    "/{tenant_name}/auth-info",
    summary="テナント認証情報の取得",
    description="認証前のテナント特定用エンドポイント。tenant_name から認証に必要な情報を取得します。",
    responses={
        status.HTTP_404_NOT_FOUND: {
            "description": "テナントが存在しない",
            "model": ErrorResponse,
        },
        status.HTTP_500_INTERNAL_SERVER_ERROR: {
            "description": "テナントの認証情報(application_client_id等)が未設定",
            "model": ErrorResponse,
        },
    },
)
@tracer.capture_method
def get_tenant_auth_info(
    connection: Annotated[Connection, Depends(get_connection_without_tenant_scope)],
    tenant_name: Annotated[str, Path(..., min_length=1, description="テナント名")],
) -> GetAuthInfoResponse:
    usecase = TenantAuthInfoUseCase.create(connection)
    try:
        auth_info = usecase.get(name=tenant_name)

    except ResourceNotFoundError as e:
        logger.warning("Tenant not found.", exc_info=e, tenant_name=tenant_name)
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail=ErrorResponse(detail=NOT_FOUND_DETAIL).model_dump(),
        ) from e

    # NOTE: テナントの認証情報(application_client_id等)がDB上に未設定の場合、リポジトリでのデータ復元時にValueErrorとなる
    except ValueError as e:
        logger.error("Value error occurred.", exc_info=e, tenant_name=tenant_name)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=ErrorResponse(detail=INTERNAL_ERROR_DETAIL).model_dump(),
        ) from e

    return GetAuthInfoResponse(
        tenant_id=auth_info.tenant_id,
        application_client_id=auth_info.user_application_client_id,
    )
