import logging
from typing import Optional, NamedTuple

from stackbot.config import settings
from stackbot.logic.utils import get_chunks
from .base import BaseClient


logger = logging.getLogger(__name__)


class StaffInfo(NamedTuple):
    login: str
    uid: str
    id: int
    telegram_account: str
    is_dismissed: bool


class StaffClient(BaseClient):
    HOST = settings.STAFF_API_HOST
    OAUTH_TOKEN = settings.STAFF_API_TOKEN

    def get_department_by_logins(self, logins: list[str]) -> dict:
        result = {}

        for chunk in get_chunks(logins, size=100):
            response = self._make_request(
                path='/v3/persons/',
                params={
                    'login': ','.join(chunk),
                    '_fields': 'department_group,official.position,login',
                    '_limit': 100,
                },
            )
            data = response.json().get('result', [])
            for item in data:
                deps = []
                for dep in item.get('department_group', {}).get('ancestors', {}):
                    deps.append(dep.get('name'))
                deps.append(item.get('department_group').get('name'))
                position = item.get('official', {}).get('position', {}).get('ru')
                answer = {'deps': ' -> '.join(deps), 'position': position}
                result[item['login']] = answer

        return result

    def get_by_telegram(self, usernames: list[str]) -> Optional[dict[str, StaffInfo]]:
        logger.info(f'Getting staff by usernames: {usernames}')
        fields = ['id', 'uid', 'login', 'telegram_accounts.value',
                  'official.is_dismissed', 'official.affiliation']
        response = self._make_request(
            path='/v3/persons/',
            params={
                'telegram_accounts.value': ','.join(usernames),
                '_fields': ','.join(fields)
            },
        )
        data = response.json().get('result', [])
        result = dict()
        for res in data:
            for account in res['telegram_accounts']:
                if account['value'] in result:
                    logger.warning(
                        'Telegram account: {} linked with several Staff profiles, omitting'.format(account['value'])
                    )
                elif res['official']['is_dismissed'] is False:
                    result[account['value']] = StaffInfo(
                        login=res['login'],
                        uid=res['uid'],
                        id=res['id'],
                        telegram_account=account['value'],
                        is_dismissed=False,
                    )
        found_usernames = {username for username in result}
        not_found = set(usernames).difference(found_usernames)
        if len(not_found):
            logger.info('Telegram accounts: {} not linked to Staff'.format(not_found))
        return result


staff_client = StaffClient()
