# Load environment variables from .env.local FIRST, before any other imports
from pathlib import Path
from dotenv import load_dotenv
import os
env_local = Path(__file__).resolve().parent.parent / ".env.local"
if env_local.exists():
    load_dotenv(env_local)
from fastapi import FastAPI, Request,APIRouter
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from contextlib import asynccontextmanager
import logging
import traceback
from fastapi import Depends
# Routers
from fastapi.openapi.utils import get_openapi

from src.HRAndCRM.controller import HR_router
from src.models.company import Company, Subscription, SubscriptionPlan
from .alerts.controller import alerts_router
from .auth.controller import company_auth_router, application_auth_router,website_api_router
from .application_management.controller import application_management_router
from .company_management.controller import company_management_router
from .companies_management.controller import companies_management_router
from .financial.controller import financial_router
from .financial.report import financial_router1
from .ai.controller import ai_router
from .common.utils import init_dynamic_db
from .forecasting.controller import forecast_router
# Database
from src.core.database import Base, engine
from fastapi.security import OAuth2PasswordBearer

BASE_DIR = Path(__file__).resolve().parents[1]

@asynccontextmanager
async def lifespan(app: FastAPI):
   

    # Database setup
    async with engine.begin() as conn:
       
        await conn.run_sync(Base.metadata.create_all)
    print("Database initialized")
    yield

    #Shutdown: Close DB engine
    await engine.dispose()
    print("Lifespan cleanup done")


from fastapi.staticfiles import StaticFiles
# FastAPI app setup
app = FastAPI(lifespan=lifespan)





# CORS middleware
app.add_middleware(
    CORSMiddleware,
    # allow_origins=["http://localhost:5173"],  
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
app.mount("/blog", StaticFiles(directory="blog"), name="blog")
def custom_openapi():
    if app.openapi_schema:
        return app.openapi_schema

    openapi_schema = get_openapi(
        title="My API with JWT",
        version="1.0.0",
        description="API with JWT token auth in Swagger",
        routes=app.routes,
    )

    openapi_schema["components"]["securitySchemes"] = {
        "BearerAuth": {
            "type": "http",
            "scheme": "bearer",
            "bearerFormat": "JWT"
        }
    }

    for path in openapi_schema["paths"].values():
        for method in path.values():
            method["security"] = [{"BearerAuth": []}]

    app.openapi_schema = openapi_schema
    return app.openapi_schema

app.openapi = custom_openapi
# Use OAuth2PasswordBearer for Swagger
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")  # Adjust path if needed
# @app.get("/protected-route")
# async def protected_route(token: str = Depends(oauth2_scheme)):
#     user = decode_token(token)
#     return {"message": f"Hello, {user['sub']}"}

#api_v1_router
api_v1_router = APIRouter(prefix="/api/v1")

#appliccation routes
api_v1_router.include_router(application_auth_router)
api_v1_router.include_router(application_management_router)
api_v1_router.include_router(companies_management_router)
api_v1_router.include_router(website_api_router)
#company routes
api_v1_router.include_router(company_auth_router)
api_v1_router.include_router(company_management_router)

#financial
api_v1_router.include_router(financial_router)
api_v1_router.include_router(financial_router1)

#ai
api_v1_router.include_router(ai_router)
api_v1_router.include_router(alerts_router)
api_v1_router.include_router(HR_router)
api_v1_router.include_router(forecast_router)
app.include_router(api_v1_router)



@app.get("/ping")
async def ping():
    return {"message": "pong"}




# Global exception handler

@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
    # Log full traceback to the logs
    logging.exception("Unhandled exception occurred")

    # Optional: extract traceback string
    tb_str = ''.join(traceback.format_exception(type(exc), exc, exc.__traceback__))

    # You can return this info to client for debugging (remove in production)
    return JSONResponse(
        status_code=500,
        content={
            "detail": "Internal server error",
            "error_type": type(exc).__name__,
            "error_message": str(exc),
            "trace": tb_str  # Optional: comment out in production for security
        }
    )


