import logging
from typing import Any, Dict, Set

from django.conf import settings

from staff.departments.controllers.proposal_action import Action
from staff.departments.controllers.tickets import RestructurisationTicket, helpers
from staff.departments.controllers.tickets.base import ProposalTicketCtlError


logger = logging.getLogger(__name__)


class HeadcountTicket(RestructurisationTicket):
    TICKET_TEMPLATE = 'startrek/headcount_ticket.html'
    queue_id = settings.HEADCOUNT_QUEUE_ID

    def get_ticket_key(self) -> str:
        return self.context.proposal_object['tickets'].get('headcount')

    def generate_ticket_context(self, enumerate_entries=True):
        return {
            'proposal_id': self.context.proposal_id,
            'vacancies': [
                self.prepare_vacancy_action_ticket_context(action)
                for action in self.ticket_dispatcher.r15n_vacancy_actions
            ],
            'headcounts': [
                self.prepare_headcount_action_ticket_context(action)
                for action in self.ticket_dispatcher.headcount_actions
            ],
            'settings': settings,
            'description': self.context.proposal_object['description'],
            'apply_at': self.get_apply_date(),
        }

    def prepare_headcount_action_ticket_context(self, action_data: Action) -> Dict[str, Any]:
        headcount_code = action_data['headcount_code']
        headcount_data = self.context.headcounts_data[headcount_code]
        headcount_context = {
            'code': headcount_code,
            'name': headcount_data['name'],
            'status': headcount_data['status'],
            'department': {
                'old': {'url': headcount_data['department__url']},
                'new': {},
            },
            'new_hr_product': None,
            'old_hr_product': None,
            'new_geography': None,
            'old_geography': None,
        }

        existing_department = action_data.get('department')
        new_department = action_data.get('fake_department')

        if existing_department:
            headcount_context['department']['new']['url'] = existing_department
        elif new_department:
            new_dep_details = self.context.dep_data[new_department]
            headcount_context['department']['new'] = new_dep_details['ru']

        headcount_code = action_data['headcount_code']
        self._put_hr_product_to_context(headcount_context, headcount_code, action_data)
        self._put_geography_to_context(headcount_context, headcount_code, action_data)

        return headcount_context

    def delete_ticket(self, author_login: str, comment_text: str) -> None:
        """
        Пока что просто пишет комментарий в тикет и удаляет ключ тикета из заявки
        """
        self.add_comment(author_login, comment_text=comment_text)
        tickets = self.context.proposal_object['tickets']
        tickets['deleted_headcount'] = tickets['headcount']
        self.ticket_key = ''
        self.update_ticket_key_in_proposal()

    def create_ticket(self, author_login=None) -> str:
        """
        Создаёт тикет в стартреке в очереди HEADCOUNT (THEADCOUNT для тестинга).
        Примеры ключей в ticket_params: summary, description, assignee, tags, followers
        Пересохраняет заявку, добавив в неё ключ тикета
        Возвращает строку с ключом тикета
        """
        if self.ticket_key:
            raise ProposalTicketCtlError(self.ticket_key)
        old_key = self.context.proposal_object['tickets'].get('deleted_headcount')
        if old_key:
            self._restore_ticket(old_key, author_login)
        else:
            self._create_ticket()
        self.update_ticket_key_in_proposal()
        return self.ticket_key

    def update_ticket_key_in_proposal(self):
        self.context.proposal.update_tickets(headcount_ticket=self.ticket_key)
        self.context.proposal.save()

    def get_unique(self):
        return f'proposal/{self.context.proposal_id}/headcount'

    def get_summary(self):
        return 'Заявка на перемещение БП'

    def get_assignee(self):
        if len(self.analysts) > 0:
            return next(iter(self.analysts))

        return helpers.department_attrs.default.analyst.login

    def _get_headcount_analysts(self) -> Set[str]:
        return {
            helpers.department_attrs.get_analyst(
                self.context.get_department(
                    self.context.headcounts_data[act['headcount_code']]['department_id']
                )
            )
            for act in self.context.headcount_actions
        } - {None}
