from intranet.femida.src.interviews.models import Interview
from intranet.femida.src.notifications.base import FetchingNotificationBase, R
from intranet.femida.src.notifications.headers import (
    get_application_headers,
    get_candidate_headers,
    get_vacancy_headers,
    get_candidate_headers_prefetched,
    get_vacancy_headers_prefetched,
)
from intranet.femida.src.notifications.utils import (
    get_candidate_message_id,
    get_hiring_managers,
    get_application_email_subject,
)

from . import serializers


vacancy_recruiters_rcv = R(lambda x: x.instance.vacancy.recruiters)
vacancy_responsibles_rcv = R(lambda x: x.instance.vacancy.responsibles)
candidate_responsibles_rcv = R(lambda x: x.instance.candidate.responsibles.all())
hiring_manager_rcv = R(lambda x: get_hiring_managers(x.instance))
initiator_rcv = R(lambda x: [x.initiator])


class ApplicationNotification(FetchingNotificationBase):

    subject_prefix = None

    def get_subject(self):
        return get_application_email_subject(self.instance, self.subject_prefix)

    def get_thread_id(self):
        return get_candidate_message_id(self.instance.candidate)

    def get_common_context(self):
        context = super().get_common_context()
        interviews = self.kwargs.get('interviews')
        interviews = interviews or Interview.unsafe.none()
        interviews = interviews.select_related('interviewer')
        context['application'] = serializers.ApplicationSerializer(self.instance).data
        context['candidate'] = serializers.CandidateSerializer(self.instance.candidate).data
        context['vacancy'] = serializers.VacancySerializer(self.instance.vacancy).data
        context['interviews'] = serializers.InterviewSerializer(interviews, many=True).data
        return context

    def get_femida_headers(self):
        headers = super().get_femida_headers()
        headers.update(get_application_headers([self.instance.id]))
        headers.update(get_candidate_headers(self.instance.candidate.id))
        headers.update(get_vacancy_headers([self.instance.vacancy.id]))
        return headers


class ApplicationResolutionChangedNotification(ApplicationNotification):

    subject_prefix = 'Изменена резолюция рассмотрения'
    template_name = 'mail/applications/resolution-change.html'
    event_type = 'application_change_resolution'
    receivers = candidate_responsibles_rcv - initiator_rcv


class ApplicationActivatedNotification(ApplicationNotification):

    subject_prefix = 'Рассматривается на вакансию'
    template_name = 'mail/applications/status-change.html'
    event_type = 'application_create'
    receivers = (
        vacancy_recruiters_rcv
        + vacancy_responsibles_rcv
        + candidate_responsibles_rcv
        + hiring_manager_rcv
        - initiator_rcv
    )


class ApplicationClosedNotification(ApplicationNotification):

    subject_prefix = 'Завершено рассмотрение'
    template_name = 'mail/applications/status-change.html'
    receivers = candidate_responsibles_rcv - initiator_rcv


class ApplicationBulkClosedNotification(ApplicationClosedNotification):
    """
    Уведомление о массовом закрытии прет-в.
    Нужно для того, чтобы хоть как-то оптимизировать отправку писем балком,
    которая стала совсем неоптимальной с тех пор, как начали использовать заголовки писем
    """

    # Задаём явно тип события.
    # Откуда бы не отправлялась отбивка, означает она всегда одно – прет-во закрыто
    event_type = 'application_close'

    def get_femida_headers(self):
        headers = self.get_default_femida_headers()
        headers.update(get_application_headers([self.instance.id]))
        headers.update(get_candidate_headers_prefetched(self.instance.candidate))
        headers.update(get_vacancy_headers_prefetched([self.instance.vacancy]))
        return headers


class AcceptProposalNotification(ApplicationNotification):

    receivers = (
        vacancy_recruiters_rcv
        + candidate_responsibles_rcv
        - initiator_rcv
    )
    template_name = 'mail/applications/proposal-accept.html'
    subject_prefix = 'Команда заинтересована'


class RejectProposalNotification(ApplicationNotification):

    receivers = candidate_responsibles_rcv - initiator_rcv
    template_name = 'mail/applications/status-change.html'
    subject_prefix = 'Завершено рассмотрение'
