from typing import Optional, Dict
import json

from django.core.management.base import BaseCommand

from staff.person.passport.external import ExtPassport, login_has_sid_668, login_has_sid_669, try_to_get_actual_login
from staff.verification.models import ExternalLogin


class Command(BaseCommand):
    help = 'Check and fix wrong passport sids'

    def handle(self, *args, **options):
        #  Сортируем, чтобы не получить ошибку наличия 669 сида на двух аккаунтах
        external_logins = ExternalLogin.objects.order_by('status_active').select_related('person')

        problems = []
        fixes = []

        for ext in external_logins:
            data = fix_external_login(ext)
            if not data:
                continue
            if data['fixed']:
                fixes.append(data)
            else:
                problems.append(data)

        self.stdout.write(json.dumps({
            'problems': problems,
            'fixes': fixes,
        }, indent=4))


def fix_external_login(ext: ExternalLogin) -> Optional[Dict]:
    data = {
        'fixed': False,
        'staff_login': ext.person.login,
        'external_login': ext.login,
    }

    try:
        ext_passport = ExtPassport(ext.login, ext.person.login)
        current_sids = (ext_passport.sid_668, ext_passport.sid_669)
    except Exception as e:
        data.update({'blackbox_error': str(e)})
        return data

    should_be_sids = (ext.status_active and login_has_sid_668(ext), ext.status_active and login_has_sid_669(ext))
    if current_sids == should_be_sids:
        return None

    ext_passport.sid_668 = should_be_sids[0]
    ext_passport.sid_669 = should_be_sids[1]

    data.update({
        'sids_fixes': {
            '668': f'{current_sids[0]} => {should_be_sids[0]}',
            '669': f'{current_sids[1]} => {should_be_sids[1]}',
        },
    })

    try:
        ext_passport.save()
        data.update({'fixed': True})
    except Exception as e:
        passport_error = str(e)
        try:
            passport_error = json.loads(passport_error)['errors'][0]
        except Exception:
            pass
        data.update({'passport_error': passport_error})

        if isinstance(passport_error, dict) and passport_error.get('code') == 'yastaffloginoccupied':
            data.update({'actual_external_login': try_to_get_actual_login(ext.person.login)})

    return data
