from datetime import datetime, time, timezone from typing import Dict, Optional from uuid import UUID from pydantic import BaseModel, Field, field_validator class EventBase(BaseModel): title: str = Field(..., min_length=1, max_length=200) description: Optional[str] = None location_name: Optional[str] = None location_address: Optional[str] = None location_url: Optional[str] = None event_date: datetime event_start_time: Optional[time] = None event_end_time: Optional[time] = None timezone: str rsvp_deadline: Optional[datetime] = None is_public: bool = False access_code: Optional[str] = None theme_id: Optional[UUID] = None custom_theme_settings: Optional[Dict] = None additional_info: Optional[Dict] = None is_active: bool = True rsvp_enabled: bool = True gift_registry_enabled: bool = True updates_enabled: bool = True max_guests_per_invitation: Optional[int] = Field(None, ge=1) contact_email: Optional[str] = None contact_phone: Optional[str] = None @field_validator('timezone') def validate_timezone(cls, v): from zoneinfo import ZoneInfo try: ZoneInfo(v) return v except Exception: raise ValueError("Invalid timezone") @field_validator('event_date') def validate_event_date(cls, v): if not v.tzinfo: v = v.replace(tzinfo=timezone.utc) now = datetime.now(tz=timezone.utc) if v < now: raise ValueError("Event date cannot be in the past") return v @field_validator('rsvp_deadline') def validate_rsvp_deadline(cls, v, values): if v: if not v.tzinfo: raise ValueError("RSVP deadline must be timezone-aware") if 'event_date' in values.data: if v > values.data['event_date']: raise ValueError("RSVP deadline must be before event date") return v class EventCreate(EventBase): slug: str = Field(..., min_length=1, pattern="^[a-z0-9-]+$") class EventUpdate(EventBase): title: Optional[str] = None event_date: Optional[datetime] = None timezone: Optional[str] = None slug: Optional[str] = Field(None, min_length=1, pattern="^[a-z0-9-]+$") class EventInDBBase(EventBase): id: UUID created_by: UUID created_at: datetime updated_at: datetime slug: str class Config: from_attributes = True class EventResponse(EventInDBBase): @field_validator('event_date') def validate_datetime(cls, v): if v.tzinfo is None: v.event_date = v.event_date.replace(tzinfo=timezone.utc) return v class Event(EventInDBBase): pass