from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import time
import json

from app.core.config import settings
from app.core.database import engine, Base
from app.core.events import init_minio_bucket
from app.api.v1 import api_router
from app.models import log as log_models

# Create tables (dev convenience; use Alembic in production)
Base.metadata.create_all(bind=engine)

app = FastAPI(
    title=settings.PROJECT_NAME,
    version=settings.VERSION,
    description=settings.DESCRIPTION,
)

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


@app.middleware("http")
async def log_requests(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    duration = int((time.time() - start_time) * 1000)

    # Skip health checks
    if request.url.path in ["/docs", "/openapi.json", "/redoc"]:
        return response

    from app.core.database import SessionLocal
    db = None
    try:
        db = SessionLocal()
        log_entry = log_models.OperationLog(
            module=request.url.path.split("/")[2] if len(request.url.path.split("/")) > 2 else "",
            action=request.url.path,
            method=request.method,
            path=str(request.url),
            ip=request.client.host if request.client else None,
            status_code=response.status_code,
            duration_ms=duration,
        )
        db.add(log_entry)
        db.commit()
    except Exception:
        pass
    finally:
        if db:
            db.close()

    return response


@app.on_event("startup")
async def startup_event():
    init_minio_bucket()
    from app.core.database import SessionLocal
    from app.services.user_service import create_initial_data
    from app.services.classification_service import init_builtin_data
    db = SessionLocal()
    try:
        create_initial_data(db)
        init_builtin_data(db)
    finally:
        db.close()


@app.get("/health")
def health_check():
    return {"status": "ok"}


app.include_router(api_router, prefix="/api/v1")
