from pydantic import BaseModel, Field, field_validator, ConfigDict
from typing import Optional
from datetime import datetime


class CalculationsessionBase(BaseModel):
    session_id: str = Field(..., min_length=1, max_length=255)
    calculation_count: int = Field(default=0, ge=0)
    user_agent: Optional[str] = None
    last_activity_at: datetime

    @field_validator("session_id")
    @classmethod
    def validate_session_id(cls, v: str) -> str:
        if not v or not v.strip():
            raise ValueError("session_id cannot be empty or whitespace")
        return v.strip()

    @field_validator("calculation_count")
    @classmethod
    def validate_calculation_count(cls, v: int) -> int:
        if v < 0:
            raise ValueError("calculation_count must be non-negative")
        return v


class CalculationsessionCreate(CalculationsessionBase):
    pass


class CalculationsessionUpdate(BaseModel):
    session_id: Optional[str] = Field(None, min_length=1, max_length=255)
    calculation_count: Optional[int] = Field(None, ge=0)
    user_agent: Optional[str] = None
    last_activity_at: Optional[datetime] = None

    @field_validator("session_id")
    @classmethod
    def validate_session_id(cls, v: Optional[str]) -> Optional[str]:
        if v is not None:
            if not v or not v.strip():
                raise ValueError("session_id cannot be empty or whitespace")
            return v.strip()
        return v

    @field_validator("calculation_count")
    @classmethod
    def validate_calculation_count(cls, v: Optional[int]) -> Optional[int]:
        if v is not None and v < 0:
            raise ValueError("calculation_count must be non-negative")
        return v


class CalculationsessionResponse(CalculationsessionBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)