from django.template import Template, Context
from rest_framework import serializers

from intranet.femida.src.api.core.fields import SafeWikiFormattedField
from intranet.femida.src.api.core.serializers import (
    FemidaSerializer,
    IdNameSerializer,
    WorkflowActionsField,
)
from intranet.femida.src.api.reminders.serializers import ReminderSerializer
from intranet.femida.src.api.users.serializers import UserSerializer
from intranet.femida.src.api.vacancies.serializers import VacancyLiteSerializer
from intranet.femida.src.communications.models import MessageTemplate, Message
from intranet.femida.src.communications.workflow import (
    InternalMessageWorkflow,
    ExternalMessageWorkflow,
    NoteWorkflow,
)


class MessageSerializerBase(FemidaSerializer):

    attachments = serializers.SerializerMethodField()
    html = SafeWikiFormattedField()
    vacancy = VacancyLiteSerializer(source='application.vacancy', default=None)

    # TODO: подумать, может, стоит как-то объединить эти 2 поля
    author = UserSerializer()
    sender = serializers.SerializerMethodField()

    # Напоминаний не бывает только на внешней коммуникации,
    # на любых других сообщениях напоминания могут быть
    reminders = serializers.SerializerMethodField()

    def get_attachments(self, obj):
        attachments = (ma.attachment for ma in obj.message_attachments.all())
        return IdNameSerializer(attachments, many=True).data

    def get_sender(self, obj):
        sender = obj.author if obj.author else obj.candidate
        return {
            'first_name': sender.first_name,
            'last_name': sender.last_name,
        }

    def get_reminders(self, obj):
        reminders = getattr(obj, 'user_reminders', [])
        return ReminderSerializer(reminders, many=True).data

    class Meta:
        model = Message
        fields = (
            'id',
            'actions',
            'application_id',
            'attachments',
            'author',
            'created',
            'email',
            'html',
            'modified',
            'sender',
            'subject',
            'text',
            'type',
            'vacancy',
            'status',
            'is_changed',
            'schedule_time',
            'reminders',
        )


class InternalMessageSerializer(MessageSerializerBase):

    actions = WorkflowActionsField(InternalMessageWorkflow)


class ExternalMessageSerializer(MessageSerializerBase):

    actions = WorkflowActionsField(ExternalMessageWorkflow)


class NoteSerializer(MessageSerializerBase):

    actions = WorkflowActionsField(NoteWorkflow)


class MessageTemplateSerializer(serializers.ModelSerializer):

    text = serializers.SerializerMethodField()

    def get_text(self, obj):
        candidate = self.root.context.get('candidate')
        # TODO: FEMIDA-5739: удалить if после релиза фронта
        context = Context({
            'candidate_name': candidate.first_name if candidate else '[ИМЯ_КАНДИДАТА]',
        })
        text = Template(obj.text).render(context)
        return text.format(interview_datetime='[ДАТА/ВРЕМЯ]')

    class Meta:
        model = MessageTemplate
        fields = (
            'id',
            'type',
            'category_name',
            'name',
            'subject',
            'text',
        )


class MessageFormSerializer(FemidaSerializer):

    attachments = serializers.SerializerMethodField()

    def get_attachments(self, obj):
        return [a.attachment_id for a in obj.message_attachments.all()]

    class Meta:
        model = Message
        fields = (
            'application',
            'attachments',
            'email',
            'subject',
            'text',
            'schedule_time',
        )


class ConsiderationMessageListFilterFormSerializer(serializers.Serializer):

    application = serializers.ReadOnlyField(source='application.id')
