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


class ConfigDataType(str, Enum):
    STRING = "STRING"
    INTEGER = "INTEGER"
    BOOLEAN = "BOOLEAN"
    JSON = "JSON"
    DECIMAL = "DECIMAL"


class SystemconfigurationBase(BaseModel):
    key: str = Field(..., min_length=1, max_length=255)
    value: str
    data_type: ConfigDataType
    description: Optional[str] = None
    modified_by_user_id: Optional[str] = None

    @field_validator("key")
    @classmethod
    def validate_key(cls, v: str) -> str:
        if not v or not v.strip():
            raise ValueError("Configuration key cannot be empty")
        if len(v) > 255:
            raise ValueError("Configuration key must not exceed 255 characters")
        return v.strip()

    @field_validator("value")
    @classmethod
    def validate_value(cls, v: str) -> str:
        if v is None:
            raise ValueError("Configuration value is required")
        return v

    @field_validator("data_type")
    @classmethod
    def validate_data_type(cls, v: ConfigDataType) -> ConfigDataType:
        if v not in ConfigDataType:
            raise ValueError(f"Invalid data type. Must be one of: {', '.join([e.value for e in ConfigDataType])}")
        return v


class SystemconfigurationCreate(SystemconfigurationBase):
    pass


class SystemconfigurationUpdate(BaseModel):
    key: Optional[str] = Field(None, min_length=1, max_length=255)
    value: Optional[str] = None
    data_type: Optional[ConfigDataType] = None
    description: Optional[str] = None
    modified_by_user_id: Optional[str] = None

    @field_validator("key")
    @classmethod
    def validate_key(cls, v: Optional[str]) -> Optional[str]:
        if v is not None:
            if not v.strip():
                raise ValueError("Configuration key cannot be empty")
            if len(v) > 255:
                raise ValueError("Configuration key must not exceed 255 characters")
            return v.strip()
        return v


class SystemconfigurationResponse(SystemconfigurationBase):
    id: str
    last_modified_date: datetime
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)