import os
import httpx
from dotenv import load_dotenv
from fastapi.templating import Jinja2Templates
from fastapi import APIRouter, HTTPException, status, Depends, Request
from fastapi.responses import RedirectResponse
from fastapi.security import OAuth2PasswordBearer
from fastapi_sso.sso.google import GoogleSSO
from jose import jwt, JWTError
from fastapi.responses import RedirectResponse, JSONResponse 
from schemas.user import Token, UserBase, User
from utils.jwt import create_access_token, verify_token # Our custom JWT utils
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from datetime import datetime
from sqlalchemy import Column, Integer, String, DateTime
from typing import Generator
from sqlalchemy.orm import Session

DJANGO_API_BASE = os.getenv("DJANGO_API_BASE")
DATABASE_URL = os.getenv('DATABASE_URL')
Base = declarative_base()
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
load_dotenv()
templates = Jinja2Templates(directory="templates")
router = APIRouter(prefix="/auth", tags=["auth"])

# --- Google SSO Configuration ---
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
GOOGLE_REDIRECT_URI = os.getenv("GOOGLE_REDIRECT_URI")
JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY")
JWT_ALGORITHM = os.getenv("ALGORITHM")

if not GOOGLE_CLIENT_ID or not GOOGLE_CLIENT_SECRET or not GOOGLE_REDIRECT_URI or not JWT_SECRET_KEY:
    raise ValueError("Missing required environment variables for Google SSO or JWT.")

google_sso = GoogleSSO(
    client_id=GOOGLE_CLIENT_ID,
    client_secret=GOOGLE_CLIENT_SECRET,
    redirect_uri=GOOGLE_REDIRECT_URI,
    allow_insecure_http=True # Set to False in production for HTTPS
)

# --- OAuth2 Bearer Token Security Scheme for Protected Endpoints ---
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/token") # Where clients get their token


def get_db() -> Generator:
    """Dependency to get a database session."""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# --- Google Login Endpoint ---
@router.get("/google/login")
async def google_login():
    """Initiates the Google SSO login process."""
    return await google_sso.get_login_redirect()

# --- Google Callback Endpoint ---
@router.get("/google/callback")
async def google_callback(request: Request,  db: Session = Depends(get_db)):
    """Handles the callback from Google after successful authentication."""
    
    
    try:
        async with google_sso:
             user_sso = await google_sso.verify_and_process(request)
        
        

        if not user_sso or not user_sso.email:
            # You might redirect to an error page or show an error
            return RedirectResponse(url="/login?error=auth_failed", status_code=status.HTTP_302_FOUND)
        access_token = create_access_token(data={
            "email": user_sso.email,
            "name": user_sso.display_name,
        })

        
        
        async with httpx.AsyncClient() as client:
            dj_response = await client.post(
                f"https://lm.backenddb.codetorise.com/user/users/",
                json={"email": user_sso.email, "name": user_sso.display_name},
                headers={"Authorization": f"Bearer {access_token}"}
            )
            
            
            if dj_response.status_code != 200:
                return RedirectResponse(url="/login?error=user_create_failed", status_code=dj_response.status_code)
        
            user_data = dj_response.json()
        
        

        
        response = RedirectResponse(url="/home", status_code=status.HTTP_302_FOUND)
        response.set_cookie(
            key="access_token",
            value=access_token,
            httponly=True,
            max_age=3600, # e.g., 1 hour, matches JWT expiry
            expires=3600,
            path="/", # Available across the entire domain
            # secure=True, # Use True in production with HTTPS
            # samesite="Lax" # Or "Strict" for stronger CSRF protection
        )

        
            
        
        return response

    
    except Exception as e:
        print(f"Error during Google callback: {e}")
        return RedirectResponse(url=f"/login?error={e}", status_code=status.HTTP_302_FOUND)

# Your get_current_user dependency would then read from the cookie:
async def get_current_user(request: Request, db: Session = Depends(get_db)) -> UserBase:
    token = request.cookies.get("access_token")
    if not token:
        return templates.TemplateResponse("login.html", {"request": request})
    
    '''
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Not authenticated",
            headers={"WWW-Authenticate": "Bearer"},
        )'''
    payload = verify_token(token)
    
    if not payload:
        return templates.TemplateResponse("login.html", {"request": request})
        '''
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Could not validate credentials",
            headers={"WWW-Authenticate": "Bearer"},
        )'''
    
   
    user_data = UserBase(email=payload.get("email"), name=payload.get("name"))
    
    return user_data

# --- Example Protected Endpoint ---
@router.get("/me", response_model=UserBase)
async def read_current_user(current_user: UserBase = Depends(get_current_user)):
    """Returns information about the current authenticated user."""
    return current_user


def create_db_tables():
    Base.metadata.create_all(bind=engine)

# --- Dependency for Database Session ---
def get_db() -> Generator:
    """Dependency to get a database session."""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()