from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import RedirectResponse
from fastapi.middleware.cors import CORSMiddleware
from dotenv import load_dotenv
from app.middleware import InputSanitizationMiddleware  # Import the middleware from the module
from fastapi.staticfiles import StaticFiles
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.exceptions import HTTPException as StarletteHTTPException

#from app.api.v1.dependencies.auth import AuthMiddleware  # Import the middleware
#gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 --certfile=cert.pem --keyfile=key.pem

if not load_dotenv():
    print("Could not load .env file or it is empty. Please check if it exists and is readable.")
    exit(1)

# Importing routers from the v1/routers/saas directory for the SaaS application features
from app.v1.routers.saas import (
    accounts, subscriptions , support, supportcustomer, users, roles, 
    login, dashboard, audit, rbac, appflow, partners, common,
    invoices
)
from app.v1.routers import crud

from app.v1.routers.cx import (
    crm, comm, ticket
)
# Importing routers from the v1/routers/dependencies directory for the Auth features
from app.v1.dependencies import (
    auth
)
# Importing routers from the v1/routers directory for the main application features

app = FastAPI()

origins = [
    "https://localhost:3004",
    "https://b114-2405-201-e03e-c023-68a9-8d42-ba43-8bc6.ngrok-free.app",

]
app.add_middleware(auth.AuthMiddleware)
app.add_middleware(
    CORSMiddleware,
    #allow_origins=["*"], 
    allow_origins=origins, #    
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
app.add_middleware(InputSanitizationMiddleware)

# Create a separate router for endpoints with CORS set to "*"
open_cors_router = FastAPI()

# Apply CORS middleware to this specific router
open_cors_router.add_middleware(
    CORSMiddleware,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.exception_handler(StarletteHTTPException)

#public access
app.mount("/public", StaticFiles(directory="public"), name="public")

# User and Authentication
app.include_router(accounts.router, prefix="/v1/accounts", tags=["Accounts"])
app.include_router(login.router, prefix="/v1/auth", tags=["Login"])
app.include_router(users.router, prefix="/v1/users", tags=["Users"])
app.include_router(roles.router, prefix="/v1/roles", tags=["Roles"])
app.include_router(rbac.router, prefix="/v1/rbac", tags=["RBAC"])
app.include_router(common.router, prefix="/v1/common", tags=["RBAC"])
app.include_router(appflow.router, prefix="/v1/appflow", tags=["Apps"])
app.include_router(partners.router, prefix="/v1/partners", tags=["Partners"])
app.include_router(audit.router, prefix="/v1/audit", tags=["Audit"])
app.include_router(dashboard.router, prefix="/v1/dashboard", tags=["Dashboard"])

app.include_router(subscriptions.router, prefix="/v1/subscriptions", tags=["Subscriptions"])
app.include_router(invoices.router, prefix="/v1/saasinvoices", tags=["SaaS Invoices"])

app.include_router(support.router, prefix="/v1/support", tags=["Support"])
app.include_router(supportcustomer.router, prefix="/v1/supportcustomer", tags=["Customer Support"])
app.include_router(crm.router, prefix="/v1/cx/crm", tags=["CRM"])

app.include_router(crud.router, prefix="/v1/crud", tags=["crud"])


# Define a list of allowed IP addresses
allowed_ips = ["127.0.0.1"]

# Custom middleware to restrict access
@app.middleware("http")
async def restrict_access(request: Request, call_next):
    client_ip = request.client.host
    if request.url.path.startswith("/docs") or request.url.path.startswith("/redoc"):
        if client_ip not in allowed_ips:
            raise HTTPException(status_code=404, detail="Forbidden")
    response = await call_next(request)
    return response

