"""
Google OAuth service for business logic.
Handles Google OAuth authentication and user creation.
"""

import logging
from datetime import timedelta

from fastapi import HTTPException, status
from sqlalchemy.orm import Session

from auth_utils import get_password_hash
from config import settings
from models import User
from schemas import TokenResponse, UserResponse
from google_oauth import (
    verify_google_token, 
    get_google_user_info, 
    create_google_oauth_url,
    exchange_code_for_tokens
)

logger = logging.getLogger(__name__)


class GoogleAuthService:
    """Service for Google OAuth operations."""
    
    @staticmethod
    def get_oauth_url() -> str:
        """Get Google OAuth authorization URL."""
        if not settings.GOOGLE_CLIENT_ID:
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Google OAuth not configured"
            )
        
        return create_google_oauth_url()
    
    @staticmethod
    def handle_oauth_callback(auth_data, db: Session, auth_service) -> TokenResponse:
        """Handle Google OAuth callback with authorization code."""
        logger.info("🔄 Google OAuth callback received")
        
        try:
            # Exchange authorization code for tokens
            token_response = exchange_code_for_tokens(auth_data.code)
            if not token_response:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="Failed to exchange authorization code"
                )
            
            # Get user info from Google
            access_token = token_response.get('access_token')
            id_token = token_response.get('id_token')
            
            if id_token:
                # Verify ID token
                google_user = verify_google_token(id_token)
            elif access_token:
                # Get user info using access token
                google_user = get_google_user_info(access_token)
            else:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="No valid token received from Google"
                )
            
            if not google_user:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="Failed to verify Google user"
                )
            
            # Get or create user
            user = GoogleAuthService._get_or_create_user(google_user, db)
            
            # Create session
            access_token = auth_service.create_user_session(user, db)
            
            return TokenResponse(
                access_token=access_token,
                expires_in=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60,
                user=UserResponse.from_orm(user)
            )
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Google OAuth callback error: {e}")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Google OAuth authentication failed"
            )
    
    @staticmethod
    def authenticate_with_token(auth_data, db: Session, auth_service) -> TokenResponse:
        """Authenticate user with Google ID token."""
        logger.info("🔄 Google token authentication received")
        
        try:
            # Verify Google ID token
            google_user = verify_google_token(auth_data.id_token)
            if not google_user:
                raise HTTPException(
                    status_code=status.HTTP_401_UNAUTHORIZED,
                    detail="Invalid Google token"
                )
            
            # Get or create user
            user = GoogleAuthService._get_or_create_user(google_user, db)
            
            # Create session
            access_token = auth_service.create_user_session(user, db)
            
            return TokenResponse(
                access_token=access_token,
                expires_in=settings.ACCESS_TOKEN_EXPIRE_MINUTES * 60,
                user=UserResponse.from_orm(user)
            )
            
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"❌ Google token authentication error: {e}")
            raise HTTPException(
                status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                detail="Google authentication failed"
            )
    
    @staticmethod
    def _get_or_create_user(google_user: dict, db: Session) -> User:
        """Get existing user or create new one from Google data."""
        # Check if user exists
        user = db.query(User).filter(User.email == google_user['email']).first()
        
        if not user:
            # Create new user
            user = User(
                email=google_user['email'],
                name=google_user.get('name', ''),
                password=get_password_hash(f"google_{google_user['sub']}"),  # Generate secure password
                user_type="partner",
                rate="free"
            )
            
            try:
                db.add(user)
                db.commit()
                db.refresh(user)
                logger.info(f"✅ New user created via Google OAuth: {google_user['email']}")
            except Exception as e:
                logger.error(f"❌ Error creating user via Google OAuth: {e}")
                db.rollback()
                raise HTTPException(
                    status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
                    detail="Error creating user"
                )
        else:
            logger.info(f"✅ Existing user logged in via Google OAuth: {google_user['email']}")
        
        return user 