# /mnt/e/genesis-system/core/api/genesis_api.py
import logging
import os
import sys
from typing import Any, Dict, Optional

from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

# Add Genesis core path to enable imports
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from core.config import GENESIS_API_PORT, GENESIS_API_HOST, ALLOWED_ORIGINS  # Assuming config.py exists
from core.system_module import SystemModule  # Assuming system_module.py exists
from core.database import Database  # Assuming database.py exists


# Logging setup
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    handlers=[
        logging.StreamHandler(sys.stdout)
    ]
)

logger = logging.getLogger(__name__)

# FastAPI app initialization
app = FastAPI(
    title="Genesis API",
    description="Unified API for all Genesis system capabilities",
    version="0.1.0",
)

# CORS configuration
app.add_middleware(
    CORSMiddleware,
    allow_origins=ALLOWED_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Dependency Injection
def get_db() -> Database:
    """Dependency injection for database access."""
    db = Database() # Replace with your specific DB initialization, e.g., passing connection string.
    try:
        yield db
    finally:
        db.close() # Or db.dispose() if using SQLAlchemy, etc.



# API Models (Pydantic)
class SystemModuleRequest(BaseModel):
    module_name: str
    method_name: str
    arguments: Optional[Dict[str, Any]] = None

class GenericResponse(BaseModel):
    success: bool
    message: str
    data: Optional[Any] = None


# API Endpoints
@app.get("/", response_model=GenericResponse, summary="Health Check")
async def health_check():
    """
    Performs a basic health check to ensure the API is running.
    """
    return GenericResponse(success=True, message="Genesis API is running", data=None)


@app.post("/module", response_model=GenericResponse, summary="Execute System Module")
async def execute_module(request: SystemModuleRequest, db: Database = Depends(get_db)):
    """
    Executes a method from a specified system module with provided arguments.

    Args:
        request (SystemModuleRequest): The request body containing the module name,
                                        method name, and arguments.
        db (Database): Database dependency.

    Returns:
        GenericResponse: A response containing the success status, message, and data.
    """
    try:
        module = SystemModule(db=db)  # Initialize system module. Replace if the module has special initialization
        method = getattr(module, request.method_name, None)
        if not method:
            raise HTTPException(status_code=404, detail=f"Method '{request.method_name}' not found in module '{request.module_name}'")

        if request.arguments:
            result = method(**request.arguments)
        else:
            result = method()

        return GenericResponse(success=True, message="Module executed successfully", data=result)

    except AttributeError as e:
        logger.error(f"AttributeError: {e}")
        raise HTTPException(status_code=404, detail=str(e))
    except Exception as e:
        logger.exception("Error executing module:")
        raise HTTPException(status_code=500, detail=str(e))



# Example - dummy DB endpoint
@app.get("/data", response_model=GenericResponse)
async def get_data(db: Database = Depends(get_db)):
    """
    Retrieves some data from the database.

    Args:
        db (Database): The database connection.

    Returns:
        GenericResponse: Response including success flag, message and the data.
    """
    try:
        data = db.get_some_data()
        return GenericResponse(success=True, message="Data retrieved successfully", data=data)
    except Exception as e:
        logger.exception("Error retrieving data:")
        raise HTTPException(status_code=500, detail=str(e))



# Main execution (for running directly)
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host=GENESIS_API_HOST, port=GENESIS_API_PORT)