import re

from django.db import migrations, transaction


def normalized_phone(value):
    phone = re.sub(r'[\s\-()]', '', str(value or ''))
    if phone.startswith('0098'):
        return '+98' + phone[4:]
    if phone.startswith('09'):
        return '+98' + phone[1:]
    if re.fullmatch(r'9\d{9}', phone):
        return '+98' + phone
    if phone.startswith('98'):
        return '+' + phone
    return phone


def merge_user(source, target, apps):
    License = apps.get_model('courses', 'SpotplayerLicense')
    Order = apps.get_model('courses', 'Order')
    Review = apps.get_model('courses', 'Review')
    LogEntry = apps.get_model('admin', 'LogEntry')

    for license_obj in License.objects.filter(user_id=source.pk):
        if License.objects.filter(user_id=target.pk, course_id=license_obj.course_id).exists():
            license_obj.delete()
        else:
            license_obj.user_id = target.pk
            license_obj.save(update_fields=['user'])
    Order.objects.filter(user_id=source.pk).update(user_id=target.pk)
    Review.objects.filter(user_id=source.pk).update(user_id=target.pk)
    LogEntry.objects.filter(user_id=source.pk).update(user_id=target.pk)
    target.groups.add(*source.groups.all())
    target.user_permissions.add(*source.user_permissions.all())
    target.name = target.name or source.name
    target.email = target.email or source.email
    target.avatar_url = target.avatar_url or source.avatar_url
    target.is_active = target.is_active or source.is_active
    target.is_staff = target.is_staff or source.is_staff
    target.is_superuser = target.is_superuser or source.is_superuser
    if (not target.password or target.password.startswith('!')) and source.password and not source.password.startswith('!'):
        target.password = source.password
    target.save()
    source.delete()


def normalize_existing_phones(apps, schema_editor):
    User = apps.get_model('courses', 'User')
    with transaction.atomic():
        for user in list(User.objects.order_by('pk')):
            if not User.objects.filter(pk=user.pk).exists():
                continue
            normalized = normalized_phone(user.phone)
            duplicate = User.objects.filter(phone=normalized).exclude(pk=user.pk).first()
            if duplicate:
                merge_user(user, duplicate, apps)
            elif normalized != user.phone:
                user.phone = normalized
                user.save(update_fields=['phone'])


class Migration(migrations.Migration):
    dependencies = [('courses', '0007_course_course_price_non_negative_and_more')]
    operations = [migrations.RunPython(normalize_existing_phones, migrations.RunPython.noop)]
