# app/models/green_space.py
from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Tuple, Any
from datetime import datetime
from enum import Enum

class GreenSpaceType(str, Enum):
    PARK = "park"
    GARDEN = "garden"
    FOREST = "forest"
    RIVERSIDE = "riverside"
    CEMETERY = "cemetery"
    PLAYGROUND = "playground"
    SPORTS_FIELD = "sports_field"
    ALLOTMENT = "allotment"
    SQUARE = "square"
    OTHER = "other"

class NoiseLevel(int, Enum):
    VERY_QUIET = 1
    QUIET = 2
    MODERATE = 3
    NOISY = 4
    VERY_NOISY = 5

class AmenityType(str, Enum):
    TOILET = "toilet"
    RESTAURANT = "restaurant"
    CAFE = "cafe"
    ICE_CREAM = "ice_cream"
    SPATI = "spati"
    PLAYGROUND = "playground"
    WATER_FEATURE = "water_feature"
    FITNESS = "fitness"
    BIKE_RENTAL = "bike_rental"
    PARKING = "parking"
    PUBLIC_TRANSPORT = "public_transport"

class Coordinates(BaseModel):
    lat: float = Field(..., ge=-90, le=90)
    lng: float = Field(..., ge=-180, le=180)

class Amenity(BaseModel):
    id: str
    name: str
    type: AmenityType
    coordinates: Coordinates
    distance_meters: int
    rating: Optional[float] = Field(None, ge=0, le=5)
    opening_hours: Optional[str] = None
    description: Optional[str] = None

class EnvironmentalFeatures(BaseModel):
    """Environmental characteristics of the green space."""
    tree_coverage_percent: int = Field(..., ge=0, le=100, description="Percentage of area covered by trees")
    shade_quality: int = Field(..., ge=0, le=100, description="Quality of shade availability")
    noise_level: NoiseLevel = Field(..., description="Average noise level")
    wildlife_diversity_score: int = Field(..., ge=0, le=100, description="Biodiversity indicator")
    water_features: bool = Field(False, description="Has ponds, fountains, or streams")
    natural_surface_percent: int = Field(..., ge=0, le=100, description="Percentage of natural vs paved surface")

class AccessibilityFeatures(BaseModel):
    """Accessibility and infrastructure features."""
    wheelchair_accessible: bool = Field(False)
    public_transport_score: int = Field(..., ge=1, le=5, description="Public transport accessibility")
    cycling_infrastructure: bool = Field(False, description="Has bike paths or bike parking")
    parking_availability: int = Field(..., ge=1, le=5, description="Car parking availability")
    lighting_quality: int = Field(..., ge=1, le=5, description="Evening lighting quality")

class RecreationFeatures(BaseModel):
    """Recreation and activity features."""
    playground_quality: int = Field(0, ge=0, le=100, description="Playground facilities quality")
    sports_facilities: bool = Field(False, description="Has sports courts, fitness equipment")
    running_paths: bool = Field(False, description="Has designated running/walking paths")
    cycling_paths: bool = Field(False, description="Has cycling paths")
    dog_friendly: bool = Field(True, description="Dogs allowed")
    bbq_allowed: bool = Field(False, description="BBQ/grilling allowed")

class PersonalityScore(BaseModel):
    """Personality-specific score with explanation."""
    personality: str
    score: int = Field(..., ge=0, le=100)
    explanation: str
    key_factors: List[str]
    recommendations: List[str]

class GreenSpace(BaseModel):
    """Complete green space model with all features and scoring."""
    # Basic info
    id: str
    name: str
    description: Optional[str] = None
    type: GreenSpaceType
    
    # Location
    coordinates: Coordinates
    neighborhood: str
    address: Optional[str] = None
    
    # Physical characteristics
    area_sqm: Optional[int] = Field(None, ge=1, description="Area in square meters")
    perimeter_m: Optional[int] = Field(None, ge=1, description="Perimeter in meters")
    
    # Features
    environmental: EnvironmentalFeatures
    accessibility: AccessibilityFeatures
    recreation: RecreationFeatures
    
    # Nearby amenities (within search radius)
    nearby_amenities: List[Amenity] = []
    
    # Personality scoring (for current request)
    current_personality_score: Optional[PersonalityScore] = None
    all_personality_scores: Optional[Dict[str, int]] = None
    
    # Metadata
    last_updated: datetime
    data_sources: List[str] = []
    confidence_score: int = Field(..., ge=0, le=100, description="Data quality confidence")

class ScoringRequest(BaseModel):
    """Request parameters for green space scoring."""
    personality: str
    location: Optional[Tuple[float, float]] = None  # (lat, lng)
    radius: int = Field(2000, ge=100, le=10000)
    neighborhood: Optional[str] = None
    min_score: int = Field(60, ge=0, le=100)
    filters: Dict[str, Any] = {}
    limit: int = Field(20, ge=1, le=100)
    include_amenities: bool = False

class LocationScore(BaseModel):
    """Score for a specific location within a green space."""
    coordinates: Coordinates
    score: int = Field(..., ge=0, le=100)
    explanation: str
    nearby_features: List[str]
    best_for: List[str]  # Best personality types for this location
    recommendations: List[str]
