from typing import List

from django.contrib.auth import get_user_model
from django.db import transaction

from .models import Tag, UserTag
from .utils import normalize_tag_name

User = get_user_model()


@transaction.atomic
def update_user_tags(user: User, tags: List[str]) -> None:
    current_user_tags = UserTag.objects.filter(user_id=user.id)

    if not tags:
        current_user_tags.delete()
        return

    normalized_tags = {normalize_tag_name(tag): tag for tag in tags}

    current_user_tags.exclude(tag__normalized_name__in=normalized_tags).delete()

    existing_tags_to_add = Tag.objects.filter(
        normalized_name__in=normalized_tags
    ).exclude(
        user_tags__user_id=user.id
    ).values(
        'id', 'normalized_name'
    )
    for tag in existing_tags_to_add:
        UserTag.objects.create(user_id=user.id, tag_id=tag.get('id'))
        normalized_tags.pop(tag.get('normalized_name'))

    current_tag_normalized_names = current_user_tags.values_list('tag__normalized_name', flat=True)
    tags_to_create = set(normalized_tags).difference(set(current_tag_normalized_names))

    for normalized_tag in tags_to_create:
        tag = Tag.objects.create(name=normalized_tags[normalized_tag])
        UserTag.objects.create(user_id=user.id, tag_id=tag.id)
