from uuid import UUID
from typing import Optional, TYPE_CHECKING
from django.contrib.auth import get_user_model
from django.db import DatabaseError

if TYPE_CHECKING:
    from sandbox.latchstring.models import User as UserType

User = get_user_model()


def confirm_api_user(
    name: str,
    cid: UUID,
    user: Optional['UserType'] = None,
    is_superuser: bool = True,
) -> 'UserType':
    """
    Make sure an API user has been created, with the needed token.
    Used for auto-creating API user on Consoles, Aspen, etc., and
    having a predictable Canonical ID for the API User is useful.
    """
    first_name = name.title()
    if user:
        update_fields = []
        if user.first_name != first_name:
            user.first_name = first_name
            user.email = f'support+{name}_api@compassfoundation.io'
            update_fields = ['first_name', 'email']
        if str(user.cid) != str(cid):
            user.cid = cid
            update_fields.append('cid')
        if update_fields:
            try:
                user.save(update_fields=update_fields)
            except DatabaseError:
                User.objects.filter(cid=cid).delete()
                user.save(update_fields=['cid'])

        return user

    data = {
        'first_name': first_name,
        'last_name': 'API',
        'username': f'{name}_api',
        'email': f'support+{name}_api@compassfoundation.io',
        'is_api': True,
        'cid': cid,
    }

    if is_superuser:
        data |= {
            'is_superuser': True,
            'is_staff': True,
        }

    api_user, _ = User.objects.update_if_changed_or_create(cid=cid, defaults=data)  # noqa

    return api_user
