"""Authentication utility functions for code resend and token refresh."""
import uuid
import random
from datetime import datetime, timedelta
from flask import current_app
from app import db
from app.models import User, EmailVerification
from app.services.token_service import generate_access_token, verify_refresh_token
from app.services.email_service import send_verification_email


def resend_verification_code(email):
    """
    Resend verification code to user email.
    
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    user = User.query.filter_by(email=email).first()
    if not user:
        return {'success': False, 'message': 'User not found', 'data': None}
    
    if user.is_email_verified:
        return {'success': False, 'message': 'Email already verified', 'data': None}
    
    # Check resend rate limit
    one_hour_ago = datetime.utcnow() - timedelta(hours=1)
    recent_codes = EmailVerification.query.filter(
        EmailVerification.email == email,
        EmailVerification.created_at >= one_hour_ago
    ).count()
    
    if recent_codes >= current_app.config['MAX_RESEND_PER_HOUR']:
        return {'success': False, 'message': 'Too many requests. Please try again later.', 'data': None}
    
    try:
        # Invalidate old codes
        EmailVerification.query.filter_by(email=email, is_used=False).update({'is_used': True})
        
        # Generate new code
        code = str(random.randint(100000, 999999))
        verification = EmailVerification(
            email=email,
            code=code,
            expiry_minutes=current_app.config['VERIFICATION_CODE_EXPIRY']
        )
        
        db.session.add(verification)
        db.session.commit()

        # Send email
        email_sent = send_verification_email(email, code)

        if not email_sent:
            current_app.logger.warning(f"Failed to send verification email to {email}")
            return {'success': False, 'message': 'Failed to send verification email. Please try again.', 'data': None}

        return {
            'success': True,
            'message': 'Verification code sent. Please check your email.',
            'data': {'email': email}
        }
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"Resend verification error: {str(e)}")
        return {'success': False, 'message': 'Failed to send verification code. Please try again.', 'data': None}


def refresh_access_token(refresh_token):
    """
    Generate new access token from refresh token.
    
    Returns:
        dict: {'success': bool, 'message': str, 'data': dict/None}
    """
    payload = verify_refresh_token(refresh_token)
    if not payload:
        return {'success': False, 'message': 'Invalid or expired refresh token', 'data': None}
    
    # Get user_id as string (SQLite stores UUIDs as strings)
    try:
        user_id = payload['user_id']
        if not user_id:
            return {'success': False, 'message': 'Invalid token payload', 'data': None}
    except KeyError:
        return {'success': False, 'message': 'Invalid token payload', 'data': None}
    
    # Query using string ID (SQLite compatibility)
    user = User.query.filter_by(id=user_id).first()
    if not user or not user.is_active:
        return {'success': False, 'message': 'User not found or inactive', 'data': None}
    
    # Generate new access token
    access_token = generate_access_token(user.id, user.role.value)
    
    return {
        'success': True,
        'message': 'Token refreshed successfully',
        'data': {
            'access_token': access_token,
            'user': user.to_dict_auth()
        }
    }