"""
Simple app creation utilities - LangChain-style ease of use
"""

from typing import List, Optional, Type
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from apex.core.config import get_settings
from apex.infrastructure.database import engine
from apex.infrastructure.database.base import Base
from apex.api.v1 import (
    auth_router,
    users_router,
    organizations_router,
    roles_router,
    permissions_router,
    modules_router,
    settings_router,
    payments_router,
)


def create_app(
    title: Optional[str] = None,
    description: Optional[str] = None,
    version: Optional[str] = None,
    models: Optional[List[Type]] = None,
    enable_auth: bool = True,
    enable_users: bool = True,
    enable_organizations: bool = True,
    enable_roles: bool = True,
    enable_permissions: bool = True,
    enable_modules: bool = True,
    enable_settings: bool = True,
    enable_payments: bool = True,
    enable_cors: bool = True,
    **kwargs
) -> FastAPI:
    """
    Create a FastAPI app with all Apex routes configured.
    
    Args:
        title: Application title
        description: Application description
        version: Application version
        models: List of SQLAlchemy models to register
        enable_auth: Enable authentication routes
        enable_users: Enable user management routes
        enable_organizations: Enable organization routes
        enable_roles: Enable role management routes
        enable_permissions: Enable permission routes
        enable_modules: Enable module/feature flag routes
        enable_settings: Enable settings routes
        enable_payments: Enable PayPal payment routes
        enable_cors: Enable CORS middleware
        **kwargs: Additional FastAPI configuration
    
    Returns:
        Configured FastAPI application
    
    Example:
        >>> from apex import create_app
        >>> from models import User, Organization
        >>> 
        >>> app = create_app(
        ...     title="My SaaS App",
        ...     models=[User, Organization]
        ... )
    """
    settings = get_settings()
    
    # Create FastAPI app
    app = FastAPI(
        title=title or settings.APP_NAME,
        description=description or "Built with Apex SaaS Framework",
        version=version or settings.APP_VERSION,
        **kwargs
    )
    
    # Add CORS middleware
    if enable_cors:
        app.add_middleware(
            CORSMiddleware,
            allow_origins=settings.CORS_ORIGINS,
            allow_credentials=settings.CORS_ALLOW_CREDENTIALS,
            allow_methods=settings.CORS_ALLOW_METHODS,
            allow_headers=settings.CORS_ALLOW_HEADERS,
        )
    
    # Include routers based on flags
    if enable_auth:
        app.include_router(auth_router, prefix="/api/auth", tags=["Authentication"])
    
    if enable_users:
        app.include_router(users_router, prefix="/api/users", tags=["Users"])
    
    if enable_organizations:
        app.include_router(organizations_router, prefix="/api/organizations", tags=["Organizations"])
    
    if enable_roles:
        app.include_router(roles_router, prefix="/api/roles", tags=["Roles"])
    
    if enable_permissions:
        app.include_router(permissions_router, prefix="/api/permissions", tags=["Permissions"])
    
    if enable_modules:
        app.include_router(modules_router, prefix="/api/modules", tags=["Modules"])
    
    if enable_settings:
        app.include_router(settings_router, prefix="/api/settings", tags=["Settings"])
    
    if enable_payments:
        app.include_router(payments_router, prefix="/api/payments", tags=["Payments"])
    
    # Add root endpoint
    @app.get("/", tags=["Root"])
    async def root():
        return {
            "message": f"Welcome to {title or settings.APP_NAME}",
            "version": version or settings.APP_VERSION,
            "docs": "/docs",
            "redoc": "/redoc"
        }
    
    # Add health check
    @app.get("/health", tags=["Health"])
    async def health_check():
        return {"status": "healthy"}
    
    return app


async def init_database(app: Optional[FastAPI] = None, echo: bool = False):
    """
    Initialize database and create all tables.
    
    Args:
        app: FastAPI application (optional)
        echo: Echo SQL statements (for debugging)
    
    Example:
        >>> await init_database()
    """
    async with engine.begin() as conn:
        await conn.run_sync(Base.metadata.create_all)


class ApexConfig:
    """Configuration for Apex application"""
    
    def __init__(
        self,
        title: Optional[str] = None,
        description: Optional[str] = None,
        version: Optional[str] = None,
        enable_auth: bool = True,
        enable_users: bool = True,
        enable_organizations: bool = True,
        enable_roles: bool = True,
        enable_permissions: bool = True,
        enable_modules: bool = True,
        enable_settings: bool = True,
        enable_payments: bool = True,
        enable_cors: bool = True,
        auto_create_tables: bool = True,
    ):
        self.title = title
        self.description = description
        self.version = version
        self.enable_auth = enable_auth
        self.enable_users = enable_users
        self.enable_organizations = enable_organizations
        self.enable_roles = enable_roles
        self.enable_permissions = enable_permissions
        self.enable_modules = enable_modules
        self.enable_settings = enable_settings
        self.enable_payments = enable_payments
        self.enable_cors = enable_cors
        self.auto_create_tables = auto_create_tables


class Apex:
    """
    Main Apex framework class - Simple, LangChain-style API.
    
    Example 1 - Minimal:
        >>> from apex import Apex
        >>> app = Apex().app
    
    Example 2 - With models:
        >>> from apex import Apex
        >>> from models import User, Organization
        >>> 
        >>> app = Apex(models=[User, Organization]).app
    
    Example 3 - With configuration:
        >>> from apex import Apex, ApexConfig
        >>> 
        >>> config = ApexConfig(
        ...     title="My SaaS App",
        ...     enable_payments=True
        ... )
        >>> app = Apex(config=config).app
    
    Example 4 - Fluent API:
        >>> app = (
        ...     Apex()
        ...     .with_auth()
        ...     .with_payments()
        ...     .build()
        ... )
    """
    
    def __init__(
        self,
        models: Optional[List[Type]] = None,
        config: Optional[ApexConfig] = None,
        title: Optional[str] = None,
        **kwargs
    ):
        """
        Initialize Apex application.
        
        Args:
            models: List of SQLAlchemy models to register
            config: ApexConfig instance
            title: Application title
            **kwargs: Additional configuration passed to create_app
        """
        self.models = models or []
        self.config = config or ApexConfig()
        
        # Override config with direct parameters
        if title:
            self.config.title = title
        
        # Create the FastAPI app
        self.app = create_app(
            title=self.config.title,
            description=self.config.description,
            version=self.config.version,
            models=self.models,
            enable_auth=self.config.enable_auth,
            enable_users=self.config.enable_users,
            enable_organizations=self.config.enable_organizations,
            enable_roles=self.config.enable_roles,
            enable_permissions=self.config.enable_permissions,
            enable_modules=self.config.enable_modules,
            enable_settings=self.config.enable_settings,
            enable_payments=self.config.enable_payments,
            enable_cors=self.config.enable_cors,
            **kwargs
        )
        
        # Auto-create tables on startup if enabled
        if self.config.auto_create_tables:
            @self.app.on_event("startup")
            async def startup_event():
                await init_database(self.app)
    
    def with_auth(self, enabled: bool = True):
        """Enable authentication routes (fluent API)"""
        self.config.enable_auth = enabled
        return self
    
    def with_users(self, enabled: bool = True):
        """Enable user management routes (fluent API)"""
        self.config.enable_users = enabled
        return self
    
    def with_organizations(self, enabled: bool = True):
        """Enable organization routes (fluent API)"""
        self.config.enable_organizations = enabled
        return self
    
    def with_roles(self, enabled: bool = True):
        """Enable role management routes (fluent API)"""
        self.config.enable_roles = enabled
        return self
    
    def with_permissions(self, enabled: bool = True):
        """Enable permission routes (fluent API)"""
        self.config.enable_permissions = enabled
        return self
    
    def with_modules(self, enabled: bool = True):
        """Enable module/feature flag routes (fluent API)"""
        self.config.enable_modules = enabled
        return self
    
    def with_settings(self, enabled: bool = True):
        """Enable settings routes (fluent API)"""
        self.config.enable_settings = enabled
        return self
    
    def with_payments(self, enabled: bool = True):
        """Enable PayPal payment routes (fluent API)"""
        self.config.enable_payments = enabled
        return self
    
    def with_cors(self, enabled: bool = True):
        """Enable CORS middleware (fluent API)"""
        self.config.enable_cors = enabled
        return self
    
    def build(self) -> FastAPI:
        """Build and return the FastAPI app (fluent API)"""
        return self.app

