import secrets

from panel.models import POSAuditLog, POSAccessLevel, POSMachine
from django.db import transaction


def make_unique_id():
    while True:
        random_number = ''.join(str(secrets.randbelow(10)) for _ in range(6))
        if not POSMachine.objects.filter(pos_unique_id=random_number).exists():
            return random_number


class POSTransferService:
    ACTION_MAP = {
        'owner': 'CHANGE_OWNER',
        'current_user': 'CHANGE_CURRENT_USER',
        'representative': 'CHANGE_REPRESENTATIVE',
    }

    @staticmethod
    @transaction.atomic
    def transfer(pos, recipient_type, recipient, performed_by):
        old_state = {
            "owner": pos.owner_id,
            "current_user": pos.current_user_id,
            "current_representative": pos.current_representative_id,
        }

        pos.current_user = None
        pos.current_representative = None

        if recipient_type == 'owner':
            pos.owner = recipient
            pos.current_user = None
            pos.current_representative = None
            if not pos.pos_unique_id:
                pos.pos_unique_id = make_unique_id()
        elif recipient_type == 'current_user':
            pos.current_user = recipient
            pos.current_representative = None

        elif recipient_type == 'representative':
            pos.current_representative = recipient
            pos.current_user = None

        pos.save()

        if recipient_type == 'owner':
            POSAccessLevel.objects.filter(pos=pos).delete()
            user_roles = recipient.role.all()
            for role in user_roles:
                if role.name in ['KillHouse', 'Steward', 'Guilds']:
                    POSAccessLevel.objects.create(
                        pos=pos,
                        name=role.name
                    )

        POSAuditLog.objects.create(
            pos=pos,
            action=POSTransferService.ACTION_MAP[recipient_type],
            performed=performed_by,
            old_value=old_state,
            new_value={
                "recipient_type": recipient_type,
                "recipient_id": recipient.id
            },
            description="انتقال دستگاه پوز"
        )

        return pos
