from datetime import datetime
from pydantic import BaseModel, Field
from typing import Optional, List, TypeVar, Generic
from pydantic.generics import GenericModel
from .basemodel import CommonBase
from .saas.subscriptions import SaaSInvoices
from enum import Enum


# Base model for Features.
class FeatureBase(CommonBase):
    name: str = Field(..., description="Name of the feature")
    display: bool = Field(True, description="Flag to indicate if the feature should be visible")
    url: str = Field(..., description="URL for the feature")
    apiurl: Optional[str] = Field(None, description="API URL for the feature (if applicable)")
    icon: str = Field(..., description="Icon identifier for the feature")
    category: str = Field(..., description="Category of the feature (e.g. 'saas' or 'platform')")
    description: Optional[str] = Field(None, description="Description of the feature")


# Domain-specific model for Cities.
class DummyCities(CommonBase):
    name: str
    state: Optional[str] = None
    country: str

# Domain-specific model for Cities.
class DVehicleCategory(CommonBase):
    name: str
    rate: Optional[float] = None
    unit: Optional[str] = None
    base_rate: Optional[float] = None

# Domain-specific model for Cities.
class DummyPriceType(CommonBase):
    name: str
    status: Optional[str] = None
    currency: str
    city: Optional[int] = None         # Field to store the associated city (e.g., city ID or name)
    pricing_file: Optional[str] = None   # Field to store file information (e.g., URL or file path)


# Domain-specific model for Locations.
class LocationsBase(CommonBase):
    name: str
    address: str
    latitude: Optional[float] = None
    longitude: Optional[float] = None  # Corrected spelling from "langitude"
    type: Optional[str] = None

# Generic model for update operations.
class CommonUpdate(BaseModel):
    user_id: Optional[str] = None       # User performing the update
    updated_date: Optional[datetime] = Field(default_factory=datetime.utcnow)

# Generic model for list responses using Pydantic generics.
ModelType = TypeVar("ModelType", bound=BaseModel)
class CommonList(GenericModel, Generic[ModelType]):
    total_count: int
    items: List[ModelType]

class Status(str, Enum):
    ACTIVE = "active"
    INACTIVE = "inactive"
    MAINTENANCE = "maintenance"

# Domain-specific model for Cities.
class PriceType(CommonBase):
    pricing_type: str
    status: Status = Field(default=Status.ACTIVE)

class Skills(CommonBase):
    name: str
    status: Status = Field(default=Status.ACTIVE)

class Checklist(CommonBase):
    name: str
    status: Status = Field(default=Status.ACTIVE)

class Addons(CommonBase):
    name: str
    status: Status = Field(default=Status.ACTIVE)

# Mapping of collection names to models defined in this module.
MODEL_MAPPING = {
    "features": FeatureBase,
    "dummycities": DummyCities,
    "dummypricetype": DummyPriceType,
    "dummyvehiclecategory": DVehicleCategory,
    "saasinvoices": SaaSInvoices,
    "pricing_types": PriceType,
    "skills": Skills,
    "checklist": Checklist,
    "addons": Addons,
    # Add more mappings here if needed.
}

def get_model_for_collection(collection_name: str):
    """
    Resolve the collection name to a Pydantic model using the mapping.
    This function is called by your routers.
    """
    model_class = MODEL_MAPPING.get(collection_name.lower())
    if model_class is None:
        raise ValueError(f"Model for collection '{collection_name}' not found.")
    return model_class
