"""
The SIGNED-IN half of the waitlist.

The two endpoints in `views.py` belong to a visitor with no account: an email
goes in, a six-digit code comes back, and the round trip exists to prove the
address is real. A signed-in user has already proved theirs — so asking them to
type it into a box and then read a code out of their inbox is a verification
step with nothing left to verify.

So this is DRF and JWT while `views.py` is plain Django and `@csrf_exempt`:
different callers, not a second style.
"""

import logging

from django.conf import settings
from drf_spectacular.utils import extend_schema
from rest_framework import status
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from .models import WaitlistEntry

logger = logging.getLogger(__name__)


def _state(user):
    entry = WaitlistEntry.objects.filter(email=user.email).first()

    return {
        # Verified is what "on the list" means. An unverified row is a code
        # somebody was sent and never used, and counting it would tell a user
        # they are on a list they are not on.
        'joined': bool(entry and entry.verified),
        'joined_at': entry.verified_at if entry and entry.verified else None,
        'launch_label': settings.LIFEY_LAUNCH_LABEL,
    }


@extend_schema(
    summary='Whether the signed-in user is on the waitlist.',
    responses={200: {'type': 'object', 'properties': {
        'joined': {'type': 'boolean'},
        'joined_at': {'type': 'string', 'format': 'date-time', 'nullable': True},
        'launch_label': {'type': 'string'},
    }}},
)
@api_view(['GET'])
@permission_classes([IsAuthenticated])
def waitlist_status(request):
    return Response(_state(request.user))


@extend_schema(
    summary='Join the waitlist as the signed-in user.',
    request=None,
    responses={200: {'type': 'object'}},
)
@api_view(['POST'])
@permission_classes([IsAuthenticated])
def waitlist_join(request):
    """
    No body. THE ADDRESS IS THE ACCOUNT'S, never one the request names — a
    body here would let a signed-in user put somebody else's address on the
    list, which is exactly what the code round trip exists to prevent.

    Idempotent: pressing the button twice is a double click, not an error.
    """
    entry, created = WaitlistEntry.objects.get_or_create(
        email=request.user.email,
        defaults={'site': 'lifey'},
    )

    if not entry.verified:
        # Verified on creation, because signing in already proved the address.
        # `verification_code` stays blank: there is no code to send and a
        # stored one would be a live credential nobody will ever use.
        entry.verified = True
        entry.verified_at = entry.verified_at or entry.created_at
        entry.verification_code = ''
        entry.code_expires_at = None
        entry.save(update_fields=[
            'verified', 'verified_at', 'verification_code', 'code_expires_at',
        ])
        logger.info('Waitlist joined by signed-in user (%s)', request.user.pk)

    return Response(_state(request.user), status=status.HTTP_200_OK)
