"""
Application Configuration Management
Uses Pydantic Settings for environment variable validation
"""
from functools import lru_cache
from pathlib import Path
from typing import List, Optional
from pydantic_settings import BaseSettings
from pydantic import Field


# Always load .env from project root (folder that contains `app/`), not the shell CWD.
_PROJECT_ROOT = Path(__file__).resolve().parent.parent
_ENV_PATH = _PROJECT_ROOT / ".env"


class Settings(BaseSettings):
    """Application settings loaded from environment variables"""
    
    # Application
    app_name: str = Field(default="Transporter Management API")
    app_version: str = Field(default="1.0.0")
    debug: bool = Field(default=False)
    environment: str = Field(default="development")
    secret_key: str = Field(default="change-this-secret-key")
    api_v1_prefix: str = Field(default="/api/v1")
    
    # Server
    host: str = Field(default="0.0.0.0")
    port: int = Field(default=8000)
    workers: int = Field(default=4)
    
    # MySQL Database
    mysql_host: str = Field(default="localhost")
    mysql_port: int = Field(default=3306)
    mysql_user: str = Field(default="root")
    mysql_password: str = Field(default="")
    mysql_database: str = Field(default="transporter_db")
    database_url: Optional[str] = None
    db_pool_size: int = Field(default=20)
    db_max_overflow: int = Field(default=10)
    db_pool_timeout: int = Field(default=30)
    
    # Redis
    redis_host: str = Field(default="localhost")
    redis_port: int = Field(default=6379)
    redis_password: str = Field(default="")
    redis_db: int = Field(default=0)
    redis_url: Optional[str] = None
    
    # JWT Authentication
    jwt_secret_key: str = Field(default="jwt-secret-key")
    jwt_algorithm: str = Field(default="HS256")
    access_token_expire_minutes: int = Field(default=30)
    refresh_token_expire_days: int = Field(default=7)
    
    # OTP (local QA only — set empty in production)
    dev_fixed_otp: str = Field(
        default="",
        description="If non-empty and ENVIRONMENT=development, send-otp stores this code instead of a random one.",
    )
    
    # Map Provider
    default_map_provider: str = Field(default="mapbox")
    mapbox_access_token: str = Field(default="")
    mapbox_api_url: str = Field(default="https://api.mapbox.com")
    google_maps_api_key: str = Field(default="")
    google_maps_api_url: str = Field(default="https://maps.googleapis.com/maps/api")
    osm_api_url: str = Field(default="https://nominatim.openstreetmap.org")
    
    # Twilio SMS/OTP
    twilio_account_sid: str = Field(default="")
    twilio_auth_token: str = Field(default="")
    twilio_phone_number: str = Field(default="")
    twilio_verify_service_sid: str = Field(default="")
    
    # Social OAuth
    google_client_id: str = Field(default="")
    google_client_secret: str = Field(default="")
    facebook_app_id: str = Field(default="")
    facebook_app_secret: str = Field(default="")
    apple_client_id: str = Field(default="")
    apple_team_id: str = Field(default="")
    apple_key_id: str = Field(default="")
    apple_private_key_path: str = Field(default="")
    
    # AWS S3
    aws_access_key_id: str = Field(default="")
    aws_secret_access_key: str = Field(default="")
    aws_region: str = Field(default="us-east-1")
    s3_bucket_name: str = Field(default="transporter-uploads")
    use_local_storage: bool = Field(default=True)
    local_upload_dir: str = Field(default="./uploads")
    
    # Email SMTP
    smtp_host: str = Field(default="smtp.gmail.com")
    smtp_port: int = Field(default=587)
    smtp_user: str = Field(default="")
    smtp_password: str = Field(default="")
    smtp_from_email: str = Field(default="noreply@example.com")
    smtp_from_name: str = Field(default="Transporter Management")
    
    # Firebase
    firebase_credentials_path: str = Field(default="")
    
    # Payment - Stripe
    stripe_secret_key: str = Field(default="")
    stripe_publishable_key: str = Field(default="")
    stripe_webhook_secret: str = Field(default="")
    
    # Ride Configuration
    default_base_fare: int = Field(default=5000)  # In cents/paise
    default_per_km_rate: int = Field(default=1500)
    default_per_minute_rate: int = Field(default=200)
    default_commission_percentage: float = Field(default=15.0)
    driver_search_radius_km: float = Field(default=10.0)
    max_driver_search_attempts: int = Field(default=3)
    bid_expiry_seconds: int = Field(default=60)
    
    # Rate Limiting
    rate_limit_per_minute: int = Field(default=100)
    rate_limit_per_hour: int = Field(default=1000)
    
    # Logging
    log_level: str = Field(default="INFO")
    log_format: str = Field(default="json")
    log_file_path: str = Field(default="./logs/app.log")
    
    # CORS
    cors_origins: List[str] = Field(default=["http://localhost:3000", "http://localhost:8080"])
    cors_allow_credentials: bool = Field(default=True)
    
    # Celery
    celery_broker_url: str = Field(default="redis://localhost:6379/1")
    celery_result_backend: str = Field(default="redis://localhost:6379/2")
    
    @property
    def get_database_url(self) -> str:
        """Construct MySQL async database URL"""
        if self.database_url:
            return self.database_url
        return f"mysql+asyncmy://{self.mysql_user}:{self.mysql_password}@{self.mysql_host}:{self.mysql_port}/{self.mysql_database}"
    
    @property
    def get_sync_database_url(self) -> str:
        """Construct MySQL sync database URL for Alembic"""
        return f"mysql+pymysql://{self.mysql_user}:{self.mysql_password}@{self.mysql_host}:{self.mysql_port}/{self.mysql_database}"
    
    @property
    def get_redis_url(self) -> str:
        """Construct Redis URL"""
        if self.redis_url:
            return self.redis_url
        if self.redis_password:
            return f"redis://:{self.redis_password}@{self.redis_host}:{self.redis_port}/{self.redis_db}"
        return f"redis://{self.redis_host}:{self.redis_port}/{self.redis_db}"
    
    class Config:
        env_file = str(_ENV_PATH)
        env_file_encoding = "utf-8"
        case_sensitive = False
        extra = "ignore"


@lru_cache()
def get_settings() -> Settings:
    """Get cached settings instance"""
    return Settings()


settings = get_settings()
