"""QuitSure Discovery -- FastAPI server.

Serves the static Next.js funnel build (web/out) under /discovery.
The funnel itself needs NO backend; this exists so the BE team's existing
setup (Apache reverse-proxy -> `uvicorn app:app`) keeps working unchanged,
and so Phase C can add Python API routes here without changing the deploy.

Run locally:   uvicorn app:app --reload --port 8081
Then open:     http://localhost:8081/   (mounts at / to match the strip-proxy)
"""
import os

from fastapi import FastAPI, Query, Request
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
OUT_DIR = os.path.join(BASE_DIR, "web", "out")

# Where the app mounts. The test/prod Apache proxy STRIPS the /discovery
# prefix before forwarding (verified 2026-06-23: /discovery/... arrives as
# /... at uvicorn), so we mount at "/" by default. If a proxy ever forwards
# the prefix through instead, set MOUNT_PREFIX=/discovery.
# (The public /discovery prefix still lives in the build's basePath + Apache.)
MOUNT_PREFIX = os.environ.get("MOUNT_PREFIX", "")
MOUNT_AT = MOUNT_PREFIX or "/"

# ── Load .env (Phase C secrets: POSTMARK_TOKEN, DB creds, GEMINI_KEY, ...) ──
_env_path = os.path.join(BASE_DIR, ".env")
if os.path.exists(_env_path):
    with open(_env_path) as _ef:
        for _line in _ef:
            _line = _line.strip()
            if _line and "=" in _line and not _line.startswith("#"):
                _k, _v = _line.split("=", 1)
                os.environ.setdefault(_k.strip(), _v.strip())

app = FastAPI(title="QuitSure Discovery")

# ─────────────────────────────────────────────────────────────────────────
# API routes (above the static mount so /discovery/api/* wins). Reuse the
# chatbot-onboarding Python stack (db.py, later Postmark/Gemini).
# ─────────────────────────────────────────────────────────────────────────
import db  # noqa: E402


@app.get(f"{MOUNT_PREFIX}/api/me")
def api_me(u: str = Query(default="")):
    """Personalization lookup for the remarketing link ?u=<vHashedEmail>.
    Returns {} on miss/error so the funnel falls back to generic copy."""
    try:
        profile = db.get_profile(u)
    except Exception:
        profile = None
    return JSONResponse(profile or {})


@app.get(f"{MOUNT_PREFIX}/api/config")
def api_config():
    """Runtime config for the funnel (so prod swaps the paywall via .env, no rebuild).
    Mirrors chatbot-onboarding's SUBSCRIPTION_URL."""
    return JSONResponse({
        "subscriptionUrl": os.environ.get("SUBSCRIPTION_URL") or None,
        "redirectToPay": os.environ.get("REDIRECT_TO_PAY", "0") == "1",
    })


@app.post(f"{MOUNT_PREFIX}/api/track-batch")
async def api_track_batch(request: Request):
    """Buffered clickstream events from the funnel → tbl_DiscoveryClickstream."""
    try:
        body = await request.json()
        n = db.insert_clickstream(body.get("sessionId"), body.get("events") or [], body.get("meta") or {})
        return JSONResponse({"ok": True, "inserted": n})
    except Exception:
        return JSONResponse({"ok": False})


@app.post(f"{MOUNT_PREFIX}/api/session")
async def api_session(request: Request):
    """Session summary upsert (answers, reached-offer, converted) → tbl_DiscoveryOnboarding."""
    try:
        body = await request.json()
        ok = db.upsert_session(body.get("sessionId"), body.get("data") or {})
        return JSONResponse({"ok": ok})
    except Exception:
        return JSONResponse({"ok": False})

# Static funnel (Next.js export). html=True -> serves index.html for
# directories and 404.html for misses. Mounted LAST so API routes win.
app.mount(MOUNT_AT, StaticFiles(directory=OUT_DIR, html=True), name="discovery")


if __name__ == "__main__":
    import uvicorn

    uvicorn.run("app:app", host="0.0.0.0", port=8081, reload=True)
