from fastapi import FastAPI, APIRouter, Request, Query
from fastapi.responses import FileResponse
from starlette.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from database import client, db
from routes.layers_router import router as layers_router
from routes.calc_router import router as calc_router
from routes.data_router import router as data_router
from routes.export_router import router as export_router
from routes.chat_router import router as chat_router
from routes.genome_router import router as genome_router
from routes.seed_router import router as seed_router
from routes.blast_router import router as blast_router
from routes.alphaflex_router import router as alphaflex_router
from routes.auth_router import router as auth_router
from routes.payments_router import router as payments_router
from routes.platform_router import router as platform_router
from routes.fano_tool_router import router as fano_tool_router
import os
import logging
import hashlib
from datetime import datetime, timezone

app = FastAPI()
api_router = APIRouter(prefix="/api")

# ─── ANALYTICS MIDDLEWARE (server-side only, invisible to users) ───
class AnalyticsMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        response = await call_next(request)
        path = request.url.path
        if path.startswith("/api/admin/") or path.startswith("/static") or path.endswith((".js", ".css", ".map", ".ico", ".png", ".jpg")):
            return response
        try:
            now = datetime.now(timezone.utc)
            ip_raw = request.client.host if request.client else "unknown"
            ip_hash = hashlib.sha256(ip_raw.encode()).hexdigest()[:16]
            ua = request.headers.get("user-agent", "")[:200]
            await db.analytics.update_one(
                {"date": now.strftime("%Y-%m-%d"), "hour": now.hour},
                {"$inc": {"hits": 1}, "$addToSet": {"ips": ip_hash}},
                upsert=True,
            )
        except Exception:
            pass
        return response


@api_router.get("/")
async def root():
    return {"message": "LIGAND Connections API"}


@api_router.get("/download/{filename}")
async def download_file(filename: str):
    allowed = {"README.md": "/app/README.md", "NARRATIVE.md": "/app/NARRATIVE.md"}
    if filename not in allowed:
        return {"error": "Not found"}
    return FileResponse(allowed[filename], media_type="text/markdown", filename=filename)


api_router.include_router(layers_router)
api_router.include_router(calc_router)
api_router.include_router(data_router)
api_router.include_router(export_router)
api_router.include_router(chat_router)
api_router.include_router(genome_router)
api_router.include_router(seed_router)
api_router.include_router(blast_router)
api_router.include_router(alphaflex_router)
api_router.include_router(auth_router)
api_router.include_router(payments_router)
api_router.include_router(platform_router)
api_router.include_router(fano_tool_router)

# ─── ADMIN ANALYTICS ENDPOINT ───
ADMIN_SECRET = os.environ.get("ANALYTICS_SECRET", "fano_admin_2026")

@api_router.get("/admin/analytics")
async def get_analytics(secret: str = Query(...), days: int = Query(default=7)):
    if secret != ADMIN_SECRET:
        return {"error": "unauthorized"}
    from datetime import timedelta
    cutoff = (datetime.now(timezone.utc) - timedelta(days=days)).strftime("%Y-%m-%d")
    cursor = db.analytics.find({"date": {"$gte": cutoff}}, {"_id": 0}).sort([("date", 1), ("hour", 1)])
    rows = await cursor.to_list(length=500)
    total_hits = sum(r.get("hits", 0) for r in rows)
    all_ips = set()
    for r in rows:
        all_ips.update(r.get("ips", []))
    for r in rows:
        r["unique_visitors"] = len(r.get("ips", []))
        del r["ips"]
    return {"total_hits": total_hits, "unique_visitors": len(all_ips), "period_days": days, "hourly": rows}

app.include_router(api_router)

app.add_middleware(AnalyticsMiddleware)

# CORS: use allow_origin_regex to reflect the actual requesting origin
# This is required because credentials:"include" + Allow-Origin:* is blocked by browsers
_cors_env = os.environ.get('CORS_ORIGINS', '*').strip()
_use_wildcard = _cors_env == '*'

app.add_middleware(
    CORSMiddleware,
    allow_credentials=True,
    allow_origins=[] if _use_wildcard else _cors_env.split(','),
    allow_origin_regex=r".*" if _use_wildcard else None,
    allow_methods=["*"],
    allow_headers=["*"],
)

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)


@app.on_event("shutdown")
async def shutdown_db_client():
    client.close()
