"""
Firebase Authentication dependency for FastAPI.

Provides:
  - get_current_subscriber()  → for protected API routes (raises 401)
  - require_subscriber()      → for protected page routes (redirects to login)
  - Session cookie creation and verification via Firebase Admin SDK
"""
import logging
from datetime import timedelta
from typing import Optional

from fastapi import Depends, HTTPException, Request, status
from fastapi.responses import RedirectResponse
import firebase_admin.auth as fb_auth

from core.config import SESSION_COOKIE_NAME, SESSION_EXPIRY_DAYS
from database.firebase_client import get_firestore

logger = logging.getLogger("chatbot.firebase_auth")


# ── Session Cookie Helpers ─────────────────────────────────────────────────────

def create_session_cookie(id_token: str) -> str:
    """
    Exchanges a short-lived Firebase ID token for a long-lived session cookie.
    The session cookie is valid for SESSION_EXPIRY_DAYS and can be revoked.
    """
    expires_in = timedelta(days=SESSION_EXPIRY_DAYS)
    session_cookie = fb_auth.create_session_cookie(id_token, expires_in=expires_in)
    return session_cookie


def verify_session_cookie(session_cookie: str) -> dict:
    """
    Verifies a Firebase session cookie and returns the decoded claims dict.
    Raises firebase_admin.auth.InvalidSessionCookieError on failure.
    """
    decoded = fb_auth.verify_session_cookie(session_cookie, check_revoked=True)
    return decoded


def revoke_session_cookie(session_cookie: str) -> None:
    """Revokes all refresh tokens for the user owning this session cookie."""
    try:
        decoded = fb_auth.verify_session_cookie(session_cookie, check_revoked=False)
        fb_auth.revoke_refresh_tokens(decoded["uid"])
    except Exception as e:
        logger.warning(f"Session revocation warning: {e}")


# ── Subscriber Profile Loader ──────────────────────────────────────────────────

async def _load_subscriber(uid: str, db) -> dict:
    """
    Loads or auto-creates a subscriber profile from Firestore `users/{uid}`.
    Returns a dict with uid, email, tier, plan details.
    """
    from datetime import datetime
    try:
        user_ref = db.collection("users").document(uid)
        user_snap = user_ref.get()

        if user_snap.exists:
            data = user_snap.to_dict()
            data["uid"] = uid
            return data

        # Auto-create profile for first-time Firebase Auth users
        firebase_user = fb_auth.get_user(uid)
        new_profile = {
            "uid": uid,
            "email": firebase_user.email or "",
            "display_name": firebase_user.display_name or "",
            "created_at": datetime.utcnow().isoformat(),
        }
        user_ref.set(new_profile)
        logger.info(f"Auto-created subscriber profile for: {firebase_user.email}")
        return new_profile

    except Exception as e:
        logger.warning(f"Could not load subscriber profile for {uid}: {e}")
        return {"uid": uid, "email": ""}


# ── FastAPI Dependencies ───────────────────────────────────────────────────────

async def get_current_subscriber(
    request: Request,
    db=Depends(get_firestore)
) -> dict:
    """
    FastAPI dependency for **API routes**.
    Reads the session cookie, verifies it, and returns the subscriber profile.
    Raises HTTP 401 if unauthenticated.
    """
    session_cookie = request.cookies.get(SESSION_COOKIE_NAME)
    if not session_cookie:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Authentication required."
        )
    try:
        decoded = verify_session_cookie(session_cookie)
        uid = decoded["uid"]
        subscriber = await _load_subscriber(uid, db)
        return subscriber
    except fb_auth.InvalidSessionCookieError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Session expired. Please log in again."
        )
    except Exception as e:
        logger.error(f"Auth error: {e}")
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Authentication failed."
        )


async def require_subscriber(
    request: Request,
    db=Depends(get_firestore)
) -> dict:
    """
    FastAPI dependency for **Jinja2 page routes**.
    Redirects to /auth/login instead of raising 401.
    """
    session_cookie = request.cookies.get(SESSION_COOKIE_NAME)
    if not session_cookie:
        return RedirectResponse(url="/auth/login", status_code=302)

    try:
        decoded = verify_session_cookie(session_cookie)
        uid = decoded["uid"]
        subscriber = await _load_subscriber(uid, db)
        if isinstance(subscriber, RedirectResponse):
            return subscriber
        return subscriber
    except fb_auth.InvalidSessionCookieError:
        response = RedirectResponse(url="/auth/login", status_code=302)
        response.delete_cookie(SESSION_COOKIE_NAME)
        return response
    except Exception as e:
        logger.error(f"Page auth error: {e}")
        return RedirectResponse(url="/auth/login", status_code=302)
