"""
NOMAZRA auth views — Pure Django JWT authentication.
No Google auth, no Firebase auth. Firebase is ONLY used for FCM notifications.
"""
import re
import uuid
import logging

from django.contrib.auth import get_user_model
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken

from .models import UserStats

logger = logging.getLogger(__name__)

User = get_user_model()

# Basic email regex — not exhaustive but catches obvious junk
EMAIL_RE = re.compile(r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')


def _user_response(user, refresh=None):
    """Standard user response payload."""
    data = {
        'user': {
            'id': str(user.id),
            'email': user.email,
            'display_name': user.display_name or user.first_name or '',
        }
    }
    if refresh:
        data['access'] = str(refresh.access_token)
        data['refresh'] = str(refresh)
    return data


@api_view(['POST'])
@permission_classes([AllowAny])
def register(request):
    email = request.data.get('email', '').strip().lower()
    phone = request.data.get('phone', '').strip()
    password = request.data.get('password', '')
    display_name = request.data.get('display_name', '').strip()[:255]

    if not email or not password:
        return Response({'error': 'Email and password required'}, status=status.HTTP_400_BAD_REQUEST)
    if not EMAIL_RE.match(email):
        return Response({'error': 'Invalid email format'}, status=status.HTTP_400_BAD_REQUEST)
    if len(password) < 8:
        return Response({'error': 'Password must be at least 8 characters'}, status=status.HTTP_400_BAD_REQUEST)
    if len(email) > 254:
        return Response({'error': 'Email too long'}, status=status.HTTP_400_BAD_REQUEST)
    if User.objects.filter(email=email).exists():
        return Response({'error': 'Email already registered'}, status=status.HTTP_409_CONFLICT)

    try:
        # firebase_uid is required (unique=True on accounts.User).
        # NOMAZRA doesn't use Firebase auth, so we set a unique placeholder.
        user = User.objects.create_user(
            username=email,
            email=email,
            password=password,
            firebase_uid=f'nomazra_{uuid.uuid4().hex}',
            signup_provider='nomazra',
            last_auth_provider='nomazra',
        )
        if display_name:
            user.display_name = display_name
            user.first_name = display_name
            user.save(update_fields=['display_name', 'first_name'])

    except Exception as e:
        logger.error("Registration failed: %s", e)
        return Response({'error': 'Registration failed'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    UserStats.objects.get_or_create(user=user)
    refresh = RefreshToken.for_user(user)

    return Response(_user_response(user, refresh), status=status.HTTP_201_CREATED)


@api_view(['POST'])
@permission_classes([AllowAny])
def login(request):
    email = request.data.get('email', '').strip().lower()
    password = request.data.get('password', '')

    if not email or not password:
        return Response({'error': 'Email and password required'}, status=status.HTTP_400_BAD_REQUEST)

    try:
        user = User.objects.get(email=email, is_active=True, is_deleted=False)
    except User.DoesNotExist:
        return Response({'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)

    if not user.check_password(password):
        return Response({'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)

    refresh = RefreshToken.for_user(user)

    return Response(_user_response(user, refresh))


@api_view(['POST'])
@permission_classes([AllowAny])
def refresh_token(request):
    token = request.data.get('refresh')
    if not token:
        return Response({'error': 'Refresh token required'}, status=status.HTTP_400_BAD_REQUEST)
    try:
        refresh = RefreshToken(token)
        return Response({
            'access': str(refresh.access_token),
            'refresh': str(refresh),
        })
    except Exception:
        return Response({'error': 'Invalid refresh token'}, status=status.HTTP_401_UNAUTHORIZED)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def me(request):
    return Response(_user_response(request.user)['user'])


@api_view(['PATCH'])
@permission_classes([IsAuthenticated])
def update_profile(request):
    user = request.user
    if 'display_name' in request.data:
        name = request.data['display_name'][:255]
        user.display_name = name
        user.first_name = name
    user.save()
    return Response(_user_response(user)['user'])


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def change_password(request):
    user = request.user
    current = request.data.get('current_password', '')
    new = request.data.get('new_password', '')

    if not user.check_password(current):
        return Response({'error': 'Current password incorrect'}, status=status.HTTP_400_BAD_REQUEST)
    if len(new) < 8:
        return Response({'error': 'Password must be at least 8 characters'}, status=status.HTTP_400_BAD_REQUEST)

    user.set_password(new)
    user.save()
    return Response({'message': 'Password changed'})


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def update_fcm_token(request):
    """Store the device FCM token for push notifications."""
    fcm_token = request.data.get('fcm_token', '').strip()
    if not fcm_token:
        return Response({'error': 'fcm_token required'}, status=status.HTTP_400_BAD_REQUEST)
    if len(fcm_token) > 500:
        return Response({'error': 'Invalid token'}, status=status.HTTP_400_BAD_REQUEST)

    request.user.fcm_token = fcm_token
    request.user.save(update_fields=['fcm_token'])
    return Response({'message': 'FCM token updated'})


@api_view(['POST'])
@permission_classes([IsAuthenticated])
def delete_account(request):
    password = request.data.get('password', '')
    if not request.user.check_password(password):
        return Response({'error': 'Incorrect password'}, status=status.HTTP_400_BAD_REQUEST)

    # Soft delete — data retained for 30 days then purged
    request.user.soft_delete()
    return Response({'message': 'Account scheduled for deletion'}, status=status.HTTP_200_OK)
