import os

from fastapi import FastAPI, Request, HTTPException, status, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from api.platform import user as platform_user, property as platform_property, channel as platform_channel

from api.feature.content import content as feature_content
from api.feature.keyword import keyword as feature_keyword
from api.feature.audience import api as feature_audience
from api.v1.feature.audience import api as feature_audience_v1
from api.feature.automation import automation as feature_automation_v1
from api.feature.automationV2 import automation as feature_automation_v2
from api.feature.ad_integration import AdConnect as feature_ad_integration
from api.settings import senders as settings_senders

from api.dashboard.profile import profile as dashboard_profile

from api.job import batch as job_batch
from api.job import automation as job_automation
from api.job import ad as job_ad
from api.job import audience as job_audience
from api.job import profile as job_profile

from api.migration import audience as migration_audience
from api.migration import import_data as migration_import_data

from api.offline import data as offline_data
from api.offline import schema as offline_schema
from api.offline import event as offline_event
from api.feature.import_data import router as import_data_router

from utility.function import Function

security = HTTPBearer(auto_error=False)
def swagger_auth(credentials: HTTPAuthorizationCredentials = Depends(security)):
    return credentials

app = FastAPI(
    title='YDM C-360',
    version="0.1.0",
    description='YDM Customer 360 Platform API Documentation'
)

PUBLIC_PATHS = {
    "/user/login",
    "/user/register",
    "/docs",
    "/openapi.json",
    "/redoc",
    "/favicon.ico"
}

PATH_STARTSWITH_EXCEPTION = {
    "/schedule",
    "/static",
    "/feature/automation/v2/execute",
    "/feature/keyword/message_labeling"
}

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

@app.middleware("http")
async def auth_middleware(request: Request, call_next):
    path = request.url.path

    if path in PUBLIC_PATHS or any(path.startswith(p) for p in PATH_STARTSWITH_EXCEPTION):
        return await call_next(request)

    auth = request.headers.get("authorization")
    if not auth:
        return JSONResponse(status_code=401, content={"detail": "Missing Authorization header"})

    user_id = Function.getUserIDFromHeader(request.headers)
    if not user_id:
        return JSONResponse(status_code=401, content={"detail": "Invalid token"})

    request.state.user_id = user_id
    return await call_next(request)

# Platform
app.include_router(platform_user.router, prefix="/user", tags=["Platform | User"], dependencies=[Depends(swagger_auth)])
app.include_router(platform_property.router, prefix="/property", tags=["Platform | Property"], dependencies=[Depends(swagger_auth)])
app.include_router(platform_channel.router, prefix="/channel", tags=["Platform | Channel"], dependencies=[Depends(swagger_auth)])

#Feature
app.include_router(feature_content.router, prefix="/feature/content", tags=["Feature | Content"], dependencies=[Depends(swagger_auth)])
app.include_router(feature_keyword.router, prefix="/feature/keyword", tags=["Feature | Keyword"], dependencies=[Depends(swagger_auth)])
app.include_router(feature_audience.router, prefix="/feature/audience/builder", tags=["Feature | Audience"], dependencies=[Depends(swagger_auth)])
app.include_router(feature_audience_v1.router, prefix="/v1/feature/audience/builder", tags=["Feature | Audience V1"], dependencies=[Depends(swagger_auth)])
app.include_router(feature_automation_v1.router, prefix="/feature/automation/v1", tags=["Feature | Automation V1"], dependencies=[Depends(swagger_auth)])
app.include_router(feature_automation_v2.router, prefix="/feature/automation/v2", tags=["Feature | Automation V2"], dependencies=[Depends(swagger_auth)])
app.include_router(feature_ad_integration.router, prefix="/feature/ad/integration", tags=["Feature | Ad Integration"], dependencies=[Depends(swagger_auth)])

#Settings
app.include_router(settings_senders.router, prefix="/settings", tags=["Settings"], dependencies=[Depends(swagger_auth)])

#Dashboard
app.include_router(dashboard_profile.router, prefix="/dashboard/profile", tags=["Dashboard | Profile"], dependencies=[Depends(swagger_auth)])

#Backgound Job
app.include_router(job_batch.router, prefix="/schedule/batch", tags=["Schedule"])
app.include_router(job_automation.router, prefix="/schedule/automation", tags=["Schedule"])
app.include_router(job_ad.router, prefix="/schedule/ad", tags=["Schedule"])
app.include_router(job_audience.router, prefix="/schedule/audience", tags=["Schedule"])
app.include_router(job_profile.router, prefix="/schedule/profile", tags=["Schedule"])

#Migration
app.include_router(migration_audience.router, prefix="/schedule/migration/audience", tags=["Migration"])
app.include_router(migration_import_data.router, prefix="/schedule/migration/import-data", tags=["Migration"])
#Offline
app.include_router(offline_data.router, prefix="/offline/data", tags=["Offline"], dependencies=[Depends(swagger_auth)])
app.include_router(offline_schema.router, prefix="/offline/schema", tags=["Offline"], dependencies=[Depends(swagger_auth)])
app.include_router(offline_event.router, prefix="/offline/event", tags=["Offline"], dependencies=[Depends(swagger_auth)])

#Import Data
app.include_router(import_data_router, prefix="/api/v1/import-data", tags=["Import Data"], dependencies=[Depends(swagger_auth)])

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=int(os.environ.get("PORT", 8080)),
        reload=True
    )