from typing import Any, Dict, List, Union

from django.conf import settings

from staff.lib.models.roles_chain import all_persons_with_roles, extract_chiefs, extract_role
from staff.lib.models.departments_chain import get_departments_tree
from staff.departments.models import DepartmentRoles

import logging
logger = logging.getLogger(__name__)

DepartmentChain = Dict[str, Union[str, List[int], Dict[str, Any]]]


def _get_direction_index(branch):
    index = None
    for i, dep in enumerate(branch):
        if dep['kind_id'] == settings.DIS_DIRECTION_KIND_ID:
            index = i
            break
    return index


def _set_chiefs_and_partners(departments_chains: Dict[int, DepartmentChain]):
    chiefs_and_partners = all_persons_with_roles(
        roles=[DepartmentRoles.HR_PARTNER.value, DepartmentRoles.CHIEF.value],
    )
    chiefs = {
        dep_id: person_data['login']
        for dep_id, person_data in extract_chiefs(chiefs_and_partners).items()
    }
    partners = {
        dep_id: [partner['login'] for partner in partners]
        for dep_id, partners in extract_role(
            chiefs_and_partners, DepartmentRoles.HR_PARTNER.value
        ).items()
    }

    for dep_chain in departments_chains.values():
        dep_chain['chiefs'] = [
            chiefs[dep_id]
            for dep_id in dep_chain['direction']['bottom_ids']
            if dep_id in chiefs
        ]
        dep_chain['hr_partners'] = [
            partners[dep_id]  # list
            for dep_id in dep_chain['ids']
            if dep_id in partners
        ]


def get_departments_chains(department_ids: List[int]) -> Dict[int, DepartmentChain]:
    deps_tree = get_departments_tree(
        departments=department_ids,
        fields=['id', 'url', 'name', 'name_en', 'kind_id'],
    )

    result = {}
    for dep_id in department_ids:
        branch = deps_tree[dep_id]

        direction_i = _get_direction_index(branch)

        top_to_direction = branch[:direction_i and direction_i + 1]
        direction_to_bottom = branch[direction_i:]

        result[dep_id] = {
            'chain_ru': ' → '.join([d['name'] for d in branch]),
            'chain_en': ' → '.join([d['name_en'] for d in branch]),
            'ids': [d['id'] for d in branch],  # reverse?
            'urls': [d['url'] for d in branch],
            'direction': {
                'chain_ru': ' → '.join([d['name'] for d in top_to_direction]),
                'bottom_ids': [d['id'] for d in direction_to_bottom]
            }
        }

    _set_chiefs_and_partners(result)
    return result
