from django.template import loader, Context
from django.template.base import Template


class MessageID(object):
    def __init__(self, subj_id, target, msg_id):
        self.subj_id = subj_id
        self.target = target
        self.msg_id = msg_id


class MessageThreadMetaclass(type):

    def __new__(mcs, name, bases, attrs):
        new_class = type.__new__(mcs, name, bases, attrs)
        transport_id = new_class.transport_id
        if transport_id:
            MessageThread._registry[transport_id] = new_class
        return new_class


class MessageThread(metaclass=MessageThreadMetaclass):
    _registry = {}
    transport_id = None

    def get_or_create(self, subj_id, target):
        from staff.django_intranet_notifications.models import MessageThreadModel
        try:
            thread = MessageThreadModel.objects.filter(
                subj_id=subj_id,
                target=target,
                transport_id=self.transport_id
            ).order_by('-last_msg_id')[0]

        except IndexError:
            thread = MessageThreadModel.objects.create(
                subj_id=subj_id,
                target=target,
                transport_id=self.transport_id,
                last_msg_id=None)

        self.subj_id = subj_id.lower()
        self.target = target.lower()
        self.instance = thread

        return self

    def get_last_id(self):
        last_id = self.instance.last_msg_id
        if last_id:
            return last_id
        else:
            return None

    def get_new_id(self):
        return self.increment(self.get_last_id())

    def increment(self, id):
        if id is None:
            return 1
        else:
            return id + 1

    def prepare_message(self, message):
        message.set_parent_id(self.get_last_id())
        message.set_id(self.get_new_id())

    def commit_message(self, message):
        self.instance.last_msg_id = message.id
        self.instance.save(force_update=True)


def message_thread_factory(transport_id):
    return MessageThread._registry[transport_id]


class Message(object):
    def __init__(self, context=None, template=None):
        super(Message, self).__init__()
        self.context = context or {}
        self.template = template
        self.recipients = []
        self.id = None
        self.parent_id = None

    def set_parent_id(self, id):
        self.parent_id = id

    def set_id(self, id):
        self.id = id

    def get_template(self):
        template_or_path = self.get_template_path()
        if isinstance(template_or_path, Template):
            return template_or_path
        return loader.get_template(template_or_path)

    def render(self):
        template = self.get_template()
        content = template.render(Context(self.context))
        subject, content_html = content.split('\n\n', 1)
        return content_html.strip(), subject.strip()

    def get_template_path(self):
        return self.template

    def send(self, **params):
        raise NotImplementedError


class FakeMessageThread(MessageThread):
    transport_id = 'fake'
