from __future__ import annotations

from datetime import datetime

from pydantic import BaseModel, Field, field_validator, model_validator


class SsoTicketRequest(BaseModel):
    externalUserId: str = Field(min_length=1, max_length=120)
    verifiedPhone: str | None = Field(default=None, min_length=11, max_length=20)
    displayName: str | None = Field(default=None, max_length=100)
    returnUrl: str | None = Field(default=None, max_length=1000)


class SsoExchangeRequest(BaseModel):
    code: str = Field(min_length=20, max_length=200)


class SsoClientSaveRequest(BaseModel):
    appId: str = Field(min_length=3, max_length=80, pattern=r"^[A-Za-z0-9][A-Za-z0-9._-]+$")
    name: str = Field(min_length=1, max_length=100)
    redirectUris: list[str] = Field(default_factory=list, max_length=20)
    allowAutoRegister: bool = False
    defaultEntitlementPlanId: int | None = Field(default=None, gt=0)
    status: int = Field(default=1, ge=0, le=1)

    @field_validator("redirectUris")
    @classmethod
    def validate_redirect_uris(cls, values: list[str]) -> list[str]:
        cleaned: list[str] = []
        for raw in values:
            value = raw.strip()
            if not value:
                continue
            if not value.startswith(("https://", "http://localhost", "http://127.0.0.1")):
                raise ValueError("回跳地址必须使用 HTTPS；本地调试可使用 localhost 或 127.0.0.1")
            if value not in cleaned:
                cleaned.append(value)
        return cleaned

    @model_validator(mode="after")
    def validate_auto_register_plan(self):
        if self.allowAutoRegister and self.defaultEntitlementPlanId is None:
            raise ValueError("允许自动注册时必须选择默认权益版本")
        return self


class SsoClientUpdateRequest(BaseModel):
    name: str = Field(min_length=1, max_length=100)
    redirectUris: list[str] = Field(default_factory=list, max_length=20)
    allowAutoRegister: bool = False
    defaultEntitlementPlanId: int | None = Field(default=None, gt=0)
    status: int = Field(default=1, ge=0, le=1)

    @field_validator("redirectUris")
    @classmethod
    def validate_redirect_uris(cls, values: list[str]) -> list[str]:
        return SsoClientSaveRequest.validate_redirect_uris(values)

    @model_validator(mode="after")
    def validate_auto_register_plan(self):
        return SsoClientSaveRequest.validate_auto_register_plan(self)


class SsoPublicConfigRequest(BaseModel):
    userClientUrl: str = Field(default="", max_length=1000)

    @field_validator("userClientUrl")
    @classmethod
    def validate_user_client_url(cls, value: str) -> str:
        cleaned = value.strip().rstrip("/")
        if cleaned and not cleaned.startswith(("https://", "http://localhost", "http://127.0.0.1")):
            raise ValueError("用户端公网地址必须使用 HTTPS；本地调试可使用 localhost 或 127.0.0.1")
        return cleaned


class SsoClientItem(BaseModel):
    id: int
    appId: str
    name: str
    redirectUris: list[str]
    allowAutoRegister: bool
    defaultEntitlementPlanId: int | None = None
    defaultEntitlementPlanName: str | None = None
    status: int
    identityCount: int
    lastUsedAt: datetime | None = None
    createdAt: datetime
    updatedAt: datetime


class SsoIdentityItem(BaseModel):
    id: int
    clientId: int
    clientName: str
    appId: str
    userId: int
    userName: str
    phone: str
    externalUserId: str
    displayNameSnapshot: str | None = None
    lastLoginAt: datetime | None = None
    createdAt: datetime


class SsoAuditItem(BaseModel):
    id: int
    appId: str | None = None
    clientName: str | None = None
    userId: int | None = None
    externalUserId: str | None = None
    action: str
    status: str
    errorMessage: str | None = None
    ip: str | None = None
    createdAt: datetime
