from apps.accounts.models import User, Occupation
from apps.geo.models import Pincode

# Service for onboarding flow

def google_login(payload):
    """
    Handles Google login. If user does not exist, creates user and marks onboarding incomplete.
    Args:
        payload (dict): { 'email': str, 'name': str }
    Returns:
        dict: { 'success': bool, 'data': {...} or 'error': str }
    """
    import logging
    logger = logging.getLogger('accounts.onboarding')
    email = payload.get('email')
    name = payload.get('name')
    if not email:
        logger.warning({'operation': 'google_login', 'error': 'Email required'})
        return {'success': False, 'error': 'Email required'}
    email = email.lower().strip()
    user = User.objects.filter(email=email).first()
    if user:
        logger.info({'operation': 'google_login', 'user_id': user.id, 'status': 'resume'})
        return {'success': True, 'data': {'user_id': str(user.id), 'onboarding_complete': user.is_onboarding_complete}}
    # Referral code generation with retry
    import uuid
    from django.db import IntegrityError
    for _ in range(5):
        referral_code = str(uuid.uuid4())[:10].replace('-', '').upper()
        try:
            user = User.objects.create(
                email=email,
                first_name=name,
                auth_provider='google',
                is_onboarding_complete=False,
                referral_code=referral_code
            )
            logger.info({'operation': 'google_login', 'user_id': user.id, 'status': 'created'})
            return {'success': True, 'data': {'user_id': str(user.id), 'onboarding_complete': False}}
        except IntegrityError:
            logger.warning({'operation': 'google_login', 'error': 'Referral code collision', 'referral_code': referral_code})
            continue
    logger.error({'operation': 'google_login', 'error': 'Referral code generation failed'})
    return {'success': False, 'error': 'Referral code generation failed'}


def complete_profile(user, payload):
    """
    Completes user onboarding with registration form data.
    Args:
        user (User): User instance
        payload (dict): registration fields
    Returns:
        dict: { 'success': bool, 'data': {...} or 'error': str }
    """
    # Validate required fields
    import logging
    logger = logging.getLogger('accounts.onboarding')
    try:
        required = ['sponsor_id', 'full_name', 'mobile', 'pan_number', 'date_of_birth', 'pincode', 'occupation', 'accept_terms']
        for field in required:
            if not payload.get(field):
                logger.warning({'operation': 'complete_profile', 'user_id': user.id, 'error': f'{field} is required'})
                return {'success': False, 'error': f'{field} is required'}
        if not payload['accept_terms']:
            logger.warning({'operation': 'complete_profile', 'user_id': user.id, 'error': 'Terms not accepted'})
            return {'success': False, 'error': 'Terms must be accepted'}
        # Unique checks (should be handled in serializer, but double-check)
        if User.objects.filter(mobile=payload['mobile']).exclude(id=user.id).exists():
            logger.warning({'operation': 'complete_profile', 'user_id': user.id, 'error': 'Mobile already exists'})
            return {'success': False, 'error': 'Mobile already exists'}
        if User.objects.filter(email=payload.get('email')).exclude(id=user.id).exists():
            logger.warning({'operation': 'complete_profile', 'user_id': user.id, 'error': 'Email already exists'})
            return {'success': False, 'error': 'Email already exists'}
        if User.objects.filter(pan_number=payload['pan_number']).exclude(id=user.id).exists():
            logger.warning({'operation': 'complete_profile', 'user_id': user.id, 'error': 'PAN already exists'})
            return {'success': False, 'error': 'PAN already exists'}
        # Sponsor locking
        if user.referred_by:
            logger.warning({'operation': 'complete_profile', 'user_id': user.id, 'error': 'Sponsor already set'})
            return {'success': False, 'error': 'Sponsor already set'}
        # Sponsor validation
        sponsor_result = validate_sponsor(payload['sponsor_id'])
        if not sponsor_result['success']:
            logger.warning({'operation': 'complete_profile', 'user_id': user.id, 'error': sponsor_result['error']})
            return {'success': False, 'error': sponsor_result['error']}
        # Pincode/location logic
        location_result = handle_location_logic(payload['pincode'], payload.get('location_input'))
        # Do not block registration if location missing
        user.mobile = payload['mobile']
        user.pan_number = payload['pan_number']
        user.date_of_birth = payload['date_of_birth']
        user.pincode_id = location_result.get('pincode_id')
        user.location = location_result.get('location')
        user.occupation_id = payload['occupation'].id if hasattr(payload['occupation'], 'id') else payload['occupation']
        user.referred_by = sponsor_result.get('sponsor_user')
        user.is_onboarding_complete = True
        user.accept_terms = True
        try:
            user.save()
        except Exception as e:
            from django.db import IntegrityError
            if isinstance(e, IntegrityError):
                logger.error({'operation': 'complete_profile', 'user_id': user.id, 'error': 'Integrity error', 'details': str(e)})
                return {'success': False, 'error': 'Duplicate data'}
            logger.error({'operation': 'complete_profile', 'user_id': user.id, 'error': 'Save error', 'details': str(e)})
            return {'success': False, 'error': 'Internal error'}
        logger.info({'operation': 'complete_profile', 'user_id': user.id, 'status': 'onboarding_complete'})
        return {'success': True, 'data': {'user_id': str(user.id), 'onboarding_complete': True}}
    except Exception as e:
        logger.error({'operation': 'complete_profile', 'user_id': user.id, 'error': 'Unhandled error', 'details': str(e)})
        return {'success': False, 'error': 'Internal error'}


def validate_sponsor(distributor_id):
    """
    Validates sponsor referral_code and fetches sponsor name.
    Returns:
        dict: { 'success': bool, 'sponsor_name': str or None, 'sponsor_user': User or None, 'error': str or None }
    """
    sponsor_user = User.objects.filter(referral_code=distributor_id).first()
    if sponsor_user:
        return {'success': True, 'sponsor_name': sponsor_user.first_name, 'sponsor_user': sponsor_user}
    return {'success': False, 'error': 'Invalid sponsor referral_code'}


def handle_location_logic(pincode, location_input=None):
    """
    Handles pincode/location logic using Pincode rows that embed location.
    Returns:
        dict: { 'success': bool, 'pincode_id': int, 'location': str or None, 'error': str or None }
    """
    pins = Pincode.objects.filter(code=pincode)
    if not pins.exists():
        return {'success': False, 'error': 'Invalid pincode'}

    if location_input:
        loc = location_input.strip()
        pin = pins.filter(location__iexact=loc).first()
        if pin:
            return {'success': True, 'pincode_id': pin.id, 'location': pin.location}
        return {'success': True, 'pincode_id': pins.first().id, 'location': loc}

    pin = pins.exclude(location='').first() or pins.first()
    return {'success': True, 'pincode_id': pin.id, 'location': pin.location}
