from dotenv import load_dotenv

load_dotenv()
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from datetime import datetime
from zoneinfo import ZoneInfo
from middleware.authorization_middleware import AuthorizationMiddleware
from routers.user_router import user_router
from routers.comment_router import comment_router
from routers.organization_registration_request import organization_registration_request_router
from fastapi.exceptions import RequestValidationError
from routers.organization_router import organization_router
from routers.label_router import label_router


app=FastAPI(
    title="Project Management Backend service",
    version='1.0.1',
    description="Task and project management backend."
)

#middlewares
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["*"],
    allow_headers=["*"],
    allow_credentials=True
)
app.add_middleware(AuthorizationMiddleware)

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
    errors = exc.errors()

    messages = []
    for err in errors:
        field = ".".join(str(x) for x in err["loc"] if x != "body")
        msg = err["msg"]

        if err["type"] == "missing":
            messages.append(f"{field} is required")
        else:
            messages.append(f"{field}: {msg}")

    return JSONResponse(
        status_code=422,
        content={
            "message": messages[0] if len(messages) == 1 else messages
        },
    )

#adding the routers now firstly creating the user router to create account
app.include_router(user_router, prefix="/api/v1/users",tags=['users'])

#adding the organization registration request router
app.include_router(organization_registration_request_router, prefix="/api/v1/organization-registration-requests", tags=['organization-registration-requests'])


#adding the organization router:
app.include_router(organization_router,prefix='/api/v1/organizations',tags=['organization'])

#adding the organization invite router
from routers.organization_invite_router import organization_invite_router
app.include_router(organization_invite_router, prefix="/api/v1/organization-invites", tags=['organization-invites'])

#adding the project router
from routers.project_router import project_router
app.include_router(project_router, prefix="/api/v1/organization-projects", tags=['organization-projects'])

#adding the ticket router
from routers.ticket_router import ticket_router
app.include_router(ticket_router, prefix="/api/v1/tickets", tags=['tickets'])

#adding the ticket router
app.include_router(label_router, prefix="/api/v1/organization-labels", tags=['organization-labels'])

#adding the workflow status router
from routers.workflow_status_router import workflow_status_router
app.include_router(workflow_status_router, prefix="/api/v1/organization-projects", tags=['organization-projects'])

#adding comment routers
app.include_router(comment_router,prefix="/api/v1/comments", tags=['comments','ticket_comments'])

#adding activity log routers
from routers.activity_log_router import activity_log_router
app.include_router(activity_log_router, prefix="/api/v1/activity-logs", tags=['activity-logs'])

#adding notification routers
from routers.notification_router import router as notification_router
app.include_router(notification_router, prefix="/api/v1")

#adding upload router
from routers.upload_router import upload_router
app.include_router(upload_router, prefix="/api/v1/upload", tags=['upload'])

#adding reports router
from routers.job_router import job_router
app.include_router(job_router, prefix="/api/v1/reports", tags=['upload'])

#adding websocket router for real-time sync
from routers.websocket_router import websocket_router
app.include_router(websocket_router, prefix="/api/v1")

#mount static files for uploads
import os
is_vercel = os.environ.get("VERCEL") == "1"
uploads_dir = "/tmp/uploads" if is_vercel else "uploads"
if is_vercel:
    os.makedirs(uploads_dir, exist_ok=True)
app.mount("/uploads", StaticFiles(directory=uploads_dir), name="uploads")


from utils.db_connect import engine
from sqlalchemy import text

@app.get("/health", tags=["Health"])
def health():
    db_status = "ok"
    try:
        with engine.connect() as connection:
            connection.execute(text("SELECT 1"))
    except Exception as e:
        db_status = f"error: {str(e)}"

    return {
        "status": "ok",
        "db_status": db_status,
        "message": "Server running fine",
        "local_time": datetime.now(
            ZoneInfo("Asia/Kolkata")
        ).strftime("%Y-%m-%d %H:%M:%S"),
    }

@app.get("/ping", tags=["Health"])
def ping():
    return {"ping": "pong"}