from intranet.femida.src.core.choices import LANGUAGES
from intranet.femida.src.interviews import choices
from intranet.femida.src.notifications import serializers
from intranet.femida.src.notifications.base import FetchingNotificationBase, R
from intranet.femida.src.notifications.headers import (
    get_vacancy_headers,
    get_application_headers,
    get_candidate_headers,
    get_candidate_headers_prefetched,
    get_vacancy_headers_prefetched,
)
from intranet.femida.src.notifications.utils import (
    get_candidate_email_subject,
    get_candidate_message_id,
    get_interview_email_subject,
)


vacancy_team_rcv = R(lambda x: x.kwargs['vacancy'].team)

candidate_responsibles_rcv = R(lambda x: x.instance.candidate.responsibles.all())
interviewer_rcv = R(lambda x: [x.instance.interviewer])
old_interviewer_rcv = R(lambda x: [x.old_interviewer])
created_by_rcv = R(lambda x: [x.instance.created_by])
not_dismissed_created_by_rcv = R(lambda x: (
    [x.instance.created_by] if not x.instance.created_by.is_dismissed else []
))
initiator_rcv = R(lambda x: [x.initiator])


def get_headers_prefetched_for_interview(interview):
    headers = get_candidate_headers_prefetched(interview.candidate)
    if interview.application:
        headers.update(get_application_headers([interview.application_id]))
        headers.update(get_vacancy_headers_prefetched([interview.application.vacancy]))
    return headers


class InterviewNotification(FetchingNotificationBase):

    subject_prefix = None

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

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

    def get_femida_headers(self):
        headers = self.get_default_femida_headers()
        headers.update(get_candidate_headers(self.instance.candidate_id))
        if self.instance.application:
            headers.update(get_application_headers([self.instance.application_id]))
            headers.update(get_vacancy_headers([self.instance.application.vacancy_id]))
        return headers


class InterviewCreatedInterviewerNotification(InterviewNotification):

    subject_prefix = 'Секция назначена'
    template_name = 'email/interviews/create.html'
    receivers = (
        candidate_responsibles_rcv
        + interviewer_rcv
        - initiator_rcv
    )
    event_type = 'interview_create'

    def get_subject(self):
        if self.instance.type == choices.INTERVIEW_TYPES.hr_screening:
            self.subject_prefix = 'HR скрининг назначен'
        return super().get_subject()


class InterviewCreatedTeamNotification(InterviewNotification):
    """
    Уведомление об интервью, привязанного к вакансии. Для команды вакансии.
    """
    subject_prefix = 'Секция назначена'
    template_name = 'mail/interviews/interview-assigned-team.html'
    receivers = (
        vacancy_team_rcv
        - interviewer_rcv
        - initiator_rcv
    )
    event_type = 'interview_create'

    def get_common_context(self):
        context = super().get_common_context()
        context['interview'] = serializers.InterviewSerializer(self.instance).data
        context['candidate'] = serializers.CandidateSerializer(self.instance.candidate).data
        context['vacancy'] = serializers.VacancySerializer(context['vacancy']).data
        return context


class InterviewCancelledNotification(InterviewNotification):

    subject_prefix = 'Секция отменена'
    template_name = 'email/interviews/cancel.html'
    receivers = (
        candidate_responsibles_rcv
        + created_by_rcv
        + interviewer_rcv
        - initiator_rcv
    )


class InterviewReassignedNotification(InterviewNotification):

    subject_prefix = 'Секция переназначена'
    template_name = 'email/interviews/reassign.html'
    receivers = (
        created_by_rcv
        + interviewer_rcv
        + old_interviewer_rcv
        - initiator_rcv
    )
    event_type = 'interview_create'

    def __init__(self, instance, initiator, old_interviewer, **kwargs):
        super().__init__(
            instance=instance,
            initiator=initiator,
            old_interviewer=old_interviewer,
            **kwargs
        )
        self.old_interviewer = old_interviewer


class InterviewFinishedNotification(InterviewNotification):

    subject_prefix = 'Секция завершена'
    template_name = 'email/interviews/finish.html'
    receivers = (
        created_by_rcv
        + interviewer_rcv
        - initiator_rcv
    )

    def get_subject(self):
        if self.instance.type == choices.INTERVIEW_TYPES.hr_screening:
            self.subject_prefix = 'HR скрининг завершен'
        return super().get_subject()


class InterviewRoundPlanningFinishedNotification(FetchingNotificationBase):

    template_name = 'mail/interview-rounds/planning-finished.html'
    receivers = created_by_rcv

    @property
    def subject_prefix(self):
        return (
            'Запланирована серия секций'
            if self.instance.status == choices.INTERVIEW_ROUND_STATUSES.planned
            else 'Не удалось запланировать серию секций'
        )

    def get_subject(self):
        return get_candidate_email_subject(self.instance.candidate, self.subject_prefix)

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

    def get_femida_headers(self):
        applications = [i.application for i in self.kwargs['interviews'] if i.application]
        headers = self.get_default_femida_headers()
        headers.update(get_candidate_headers_prefetched(self.instance.candidate))
        headers.update(get_application_headers([a.id for a in applications]))
        headers.update(get_vacancy_headers_prefetched([a.vacancy for a in applications]))
        return headers

    def get_common_context(self):
        context = super().get_common_context()
        context['interviews'] = [self._serialize_interview(i) for i in self.kwargs['interviews']]
        context['title'] = self.subject_prefix
        return context

    def _serialize_interview(self, interview):
        data = serializers.InterviewSerializer(interview).data
        data['event_start_time'] = interview.event_start_time
        return data


class InterviewEstimatedNotification(FetchingNotificationBase):

    template_name = 'sms/interview-estimate.txt'
    supported_languages = [LANGUAGES.ru, LANGUAGES.en]
    receivers = not_dismissed_created_by_rcv
    transport = 'sms'


def notify_about_interview_create(interview, initiator, event, headers=None):
    interviewer_notification = InterviewCreatedInterviewerNotification(
        instance=interview,
        initiator=initiator,
        headers=headers,
        event=event,
    )
    interviewer_notification.send()

    if interview.application is not None:
        team_notification = InterviewCreatedTeamNotification(
            instance=interview,
            initiator=initiator,
            headers=headers,
            vacancy=interview.application.vacancy,
            event=event,
        )
        team_notification.send()


def notify_about_interview_estimate(interview):
    notification = InterviewEstimatedNotification(instance=interview)
    notification.send()
