from contextlib import asynccontextmanager
from pathlib import Path

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from fastapi.staticfiles import StaticFiles
from sqlalchemy import text

from database import engine, Base, SessionLocal

# Import all models so Base.metadata is fully populated before create_all().
import model  # noqa: F401
from model.admin import Admin
from core.security import hash_password

# Routers
from routers import admin_auth, hierarchy, doctors, dashboard, doctor_auth, patients

# Default admin seeded on first run (change the password after logging in).
DEFAULT_ADMIN_USERNAME = "admin"
DEFAULT_ADMIN_PASSWORD = "admin123"


def init_db() -> None:
    Base.metadata.create_all(bind=engine)
    db = SessionLocal()
    try:
        if not db.query(Admin).filter(Admin.username == DEFAULT_ADMIN_USERNAME).first():
            db.add(Admin(
                name="Super Admin",
                username=DEFAULT_ADMIN_USERNAME,
                password=hash_password(DEFAULT_ADMIN_PASSWORD),
            ))
            db.commit()
            print(f"[seed] Created default admin '{DEFAULT_ADMIN_USERNAME}' "
                  f"/ '{DEFAULT_ADMIN_PASSWORD}'")
    finally:
        db.close()


@asynccontextmanager
async def lifespan(app: FastAPI):
    init_db()
    yield


app = FastAPI(title="BLE Admin Panel API", version="0.1.0", lifespan=lifespan)

# The web admin panel (separate origin) needs CORS. Wide-open for dev;
# tighten allow_origins to the real frontend URL before production.
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],      # frontend is on a different subdomain
    allow_credentials=False,  # no cookies are used, so "*" is valid
    allow_methods=["*"],
    allow_headers=["*"],
)

app.include_router(admin_auth.router)
app.include_router(doctor_auth.router)
app.include_router(hierarchy.router)
app.include_router(doctors.router)
app.include_router(patients.router)
app.include_router(dashboard.router)


@app.get("/health", tags=["Health"])
def home():
    return {"message": "API Running"}


@app.get("/db-test", tags=["Health"])
def db_test():
    try:
        with engine.connect() as conn:
            db_name = conn.execute(text("SELECT current_database()")).scalar()
        return {"status": "Connected", "database": db_name}
    except Exception as e:
        return {"error": str(e)}


# ---- serve the admin panel (single-server deployment) ----------------------
# The static frontend is served at /app so the whole product runs from ONE
# server. Opening "/" redirects there. The frontend calls the API on the same
# origin, so no IP/URL editing is needed when this moves between machines.
FRONTEND_DIR = Path(__file__).resolve().parent.parent / "frontend"


@app.get("/", include_in_schema=False)
def root():
    return RedirectResponse(url="/app/")


if FRONTEND_DIR.is_dir():
    app.mount("/app", StaticFiles(directory=str(FRONTEND_DIR), html=True), name="panel")
