from enum import StrEnum

from pydantic import BaseModel, Field

# 各ステータスコード用の定型メッセージ
NOT_FOUND_DETAIL = "Requested resource was not found."
CONFLICT_DETAIL = "Conflict detected for one or more fields."
VALIDATION_FAILED_DETAIL = "Validation failed for one or more fields."
INTERNAL_ERROR_DETAIL = "An unexpected error occurred. Please try again later."


class ErrorCode(StrEnum):
    ALREADY_EXISTS = "ALREADY_EXISTS"
    INVALID_FORMAT = "INVALID_FORMAT"
    REQUIRED = "REQUIRED"
    TOO_LARGE = "TOO_LARGE"
    TOO_MANY = "TOO_MANY"


class InvalidParameter(BaseModel):
    name: str = Field(
        ...,
        description="""入力エラーが発生したパラメータ名。\n
ネストした項目はドット区切り、配列要素は 0 始まりの添字を角括弧で表します。\n
例: \n
- display_id
- file.headers.display_name
- users[0].email
""",
    )
    code: ErrorCode = Field(
        ...,
        description="""エラーの種別。codeはErrorCode型で、いずれかの値を取ります。\n
- 409: ALREADY_EXISTS \n
- 422: INVALID_FORMAT / REQUIRED / TOO_LARGE / TOO_MANY""",
    )


class ErrorResponse(BaseModel):
    detail: str = Field(..., description="エラーメッセージ")
    invalid_parameters: list[InvalidParameter] | None = Field(
        default=None,
        description="入力パラメータに問題があった場合のみ含まれる。問題のあったパラメータとエラーの種別を表すリスト",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "detail": VALIDATION_FAILED_DETAIL,
                    "invalid_parameters": [
                        {"name": "email", "code": ErrorCode.ALREADY_EXISTS},
                        {"name": "users[0].display_id", "code": ErrorCode.REQUIRED},
                        {"name": "file.headers.display_name", "code": ErrorCode.ALREADY_EXISTS},
                    ],
                },
                {
                    "detail": CONFLICT_DETAIL,
                    "invalid_parameters": [
                        {"name": "email", "code": ErrorCode.ALREADY_EXISTS},
                    ],
                },
                {
                    "detail": NOT_FOUND_DETAIL,
                },
            ],
        },
    }
