import logging

from django.conf import settings
from google.oauth2 import id_token as google_id_token
from google.auth.transport import requests as google_requests
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework_simplejwt.tokens import RefreshToken

from apps.core.utils import error_response
from apps.accounts.models import User
from apps.accounts.serializers import UserSerializer, GoogleTokenLoginSerializer
from apps.accounts.serializers_onboarding import CompleteProfileSerializer
from apps.accounts.services import onboarding_service

logger = logging.getLogger(__name__)


class GoogleLoginView(APIView):
    """
    POST /api/v1/web/auth/google-login
    Accepts: { "token": "<google_id_token>" }

    1. Verifies the Google ID token server-side.
    2. Rejects if Google email is not verified.
    3. Finds existing user or creates a new one.
    4. Rejects inactive users.
    5. Returns JWT access/refresh tokens + user data.
    """

    def post(self, request):
        serializer = GoogleTokenLoginSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        token = serializer.validated_data['token']

        # --- Step 1: Verify the Google ID token ---
        try:
            idinfo = google_id_token.verify_oauth2_token(
                token,
                google_requests.Request(),
                settings.GOOGLE_CLIENT_ID,
            )
        except ValueError as exc:
            logger.warning('Google token verification failed: %s', exc)
            return error_response(
                message='Invalid or expired Google token',
                code='INVALID_GOOGLE_TOKEN',
                status_code=status.HTTP_401_UNAUTHORIZED,
            )

        # --- Step 2: Reject unverified Google email ---
        if not idinfo.get('email_verified', False):
            logger.warning('Google login rejected: email not verified for %s', idinfo.get('email'))
            return error_response(
                message='Google email is not verified',
                code='GOOGLE_EMAIL_NOT_VERIFIED',
                status_code=status.HTTP_403_FORBIDDEN,
            )

        # --- Step 3: Extract claims ---
        email = idinfo.get('email')
        if not email:
            logger.warning('Google login rejected: no email in token')
            return error_response(
                message='Google account has no email address',
                code='GOOGLE_EMAIL_MISSING',
                status_code=status.HTTP_400_BAD_REQUEST,
            )

        google_id = idinfo.get('sub')
        first_name = idinfo.get('given_name', idinfo.get('name', ''))
        last_name = idinfo.get('family_name', '')
        picture = idinfo.get('picture')

        # --- Step 4: Find or create user ---
        user = User.objects.filter(email=email).first()

        if user:
            # Existing user — reject if deactivated
            if not user.is_active:
                logger.warning('Google login rejected: inactive user %s', user.id)
                return error_response(
                    message='Account is deactivated. Please contact support.',
                    code='ACCOUNT_INACTIVE',
                    status_code=status.HTTP_403_FORBIDDEN,
                )
            # Backfill google_id if missing
            if not user.google_id:
                user.google_id = google_id
                user.auth_provider = 'google'
                user.is_email_verified = True
                if picture:
                    user.google_avatar_url = picture
                    user.save(update_fields=['google_id', 'auth_provider', 'is_email_verified', 'google_avatar_url'])
                else:
                    user.save(update_fields=['google_id', 'auth_provider', 'is_email_verified'])
            elif picture and user.google_avatar_url != picture:
                user.google_avatar_url = picture
                user.save(update_fields=['google_avatar_url'])
            logger.info('Google login: existing user %s (%s)', user.id, email)
        else:
            # New user via Google — active immediately (no OTP needed)
            user = User.objects.create_google_user(
                email=email,
                google_id=google_id,
                first_name=first_name,
                last_name=last_name,
                google_avatar_url=picture,
                is_active=True,
            )
            logger.info('Google login: created user %s (%s)', user.id, email)

        # --- Step 5: Issue JWT tokens ---
        refresh = RefreshToken.for_user(user)

        # --- Step 6: Return response ---
        logger.debug('Google login success: user %s, onboarding=%s', user.id, user.is_onboarding_complete)
        return Response({
            'success': True,
            'data': {
                'access_token': str(refresh.access_token),
                'refresh_token': str(refresh),
                'user': UserSerializer(user, context={'request': request}).data,
                'onboarding_complete': user.is_onboarding_complete,
            },
        }, status=status.HTTP_200_OK)

class CompleteProfileView(APIView):
    def post(self, request):
        serializer = CompleteProfileSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        user_id = serializer.validated_data.get('user_id')
        user = User.objects.filter(id=user_id).first()
        if not user:
            return error_response(
                message="User not found",
                code="USER_NOT_FOUND",
                status_code=status.HTTP_404_NOT_FOUND
            )
        result = onboarding_service.complete_profile(user, serializer.validated_data)
        if not result['success']:
            return error_response(
                message=result.get('error', 'Profile completion failed'),
                code="COMPLETE_PROFILE_FAILED",
                status_code=status.HTTP_400_BAD_REQUEST
            )
        return Response({'success': True, 'data': result['data']}, status=status.HTTP_200_OK)
