from contextlib import asynccontextmanager
from pathlib import Path
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse
from jinja2 import Environment, FileSystemLoader
from starlette.middleware.base import BaseHTTPMiddleware
from app.database import engine, Base, SessionLocal
from app.models import User
from app.seed import seed
from app.routers import contracts, admin, auth, positions, trades

TEMPLATES_DIR = Path(__file__).parent / "templates"


def setup_jinja(app: FastAPI):
    env = Environment(loader=FileSystemLoader(str(TEMPLATES_DIR)))
    app.state.templates = env


class AuthMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        # Public paths
        if request.url.path in ("/auth/login", "/auth/logout") or request.url.path.startswith("/auth/"):
            return await call_next(request)

        # Check session
        user_id = request.cookies.get("ft_session")
        if user_id:
            db = SessionLocal()
            try:
                user = db.query(User).filter(User.id == int(user_id)).first()
                if user:
                    request.state.user = user
                    return await call_next(request)
            except (ValueError, TypeError):
                pass
            finally:
                db.close()

        # Redirect to login
        return RedirectResponse(f"/auth/login?next={request.url.path}", status_code=303)


@asynccontextmanager
async def lifespan(app: FastAPI):
    setup_jinja(app)
    Base.metadata.create_all(bind=engine)
    seed()
    yield


app = FastAPI(title="期货量化系统", lifespan=lifespan)

app.add_middleware(AuthMiddleware)

app.include_router(auth.router)
app.include_router(contracts.router)
app.include_router(admin.router)
app.include_router(positions.router)
app.include_router(trades.router)


@app.get("/")
def root():
    return RedirectResponse("/contracts")
