# -*- coding: utf-8 -*-
"""Vocabularies."""
from collective.dms.basecontent.dmsfile import IDmsAppendixFile
from collective.dms.basecontent.dmsfile import IDmsFile
from collective.dms.mailcontent import _tr
from collective.dms.mailcontent.dmsmail import IDmsOutgoingMail
from imio.helpers.content import find
from plone import api
from Products.CMFPlone.utils import safe_unicode
from zope.annotation import IAnnotations
from zope.interface import implements
from zope.schema.interfaces import IVocabularyFactory
from zope.schema.vocabulary import SimpleTerm
from zope.schema.vocabulary import SimpleVocabulary


class EmailAttachmentsVocabulary(object):
    """Vocabulary listing outgoing mail files and related ones, as possible email attachments"""

    implements(IVocabularyFactory)

    def __call__(self, context):
        terms = []
        # first we find context files, unrestrictedly
        brains = find(
            context=context,
            unrestricted=True,
            object_provides=[IDmsAppendixFile.__identifier__, IDmsFile.__identifier__],
            sort_on="created",
            sort_order="descending",
        )
        for brain in brains:
            obj = brain._unrestrictedGetObject()
            annot = IAnnotations(obj)
            # Do not include work mailing document (from collective.documentgenerator)
            if (
                "documentgenerator" in annot
                and "need_mailing" in annot["documentgenerator"]
                and annot["documentgenerator"]["need_mailing"]
            ):
                continue
            ftitle = safe_unicode(brain.Title)
            # Do not include filename if the file is generated by application
            if ftitle.lower() == obj.file.filename.lower() or not IDmsAppendixFile.providedBy(obj):
                title = ftitle
            else:
                title = u"{}  (« {} »)".format(ftitle, obj.file.filename)
            # TODO Mark signed version
            if getattr(brain, "signed", False):  # from collective.dms.scanbehavior
                typ = u"{} signed".format(brain.portal_type)
            else:
                typ = brain.portal_type
            terms.append(
                SimpleTerm(brain.UID, brain.UID, _tr(u"({}) => ${{title}}".format(typ), mapping={"title": title}))
            )
        # then we find files of related mails
        pc = api.portal.get_tool("portal_catalog")
        for rv in getattr(context, "reply_to", []) or []:
            is_om = IDmsOutgoingMail.providedBy(rv.to_object)
            brains = pc.unrestrictedSearchResults(
                path=rv.to_path,
                object_provides=[IDmsAppendixFile.__identifier__, IDmsFile.__identifier__],
                sort_on="created",
                sort_order="descending",
            )
            for brain in brains:
                obj = brain._unrestrictedGetObject()
                ftitle = safe_unicode(brain.Title)
                annot = IAnnotations(obj)
                # Do not include work mailing document when linked object is an outgoingmail
                if (
                    "documentgenerator" in annot
                    and "need_mailing" in annot["documentgenerator"]
                    and annot["documentgenerator"]["need_mailing"]
                ):
                    continue
                ftitle = safe_unicode(brain.Title)
                # Do not include filename if linked object is an outgoingmmail and the file is generated by application
                if ftitle.lower() == obj.file.filename.lower() or (is_om and not IDmsAppendixFile.providedBy(obj)):
                    title = ftitle
                else:
                    title = u"{}  (« {} »)".format(ftitle, obj.file.filename)
                if getattr(brain, "signed", False):  # from collective.dms.scanbehavior
                    typ = u"{} signed".format(brain.portal_type)
                else:
                    typ = brain.portal_type
                terms.append(
                    SimpleTerm(
                        brain.UID,
                        brain.UID,
                        _tr(
                            u"${{ref}} ({}) => ${{title}}".format(typ),
                            mapping={"ref": rv.to_object.internal_reference_no, "title": title},
                        ),
                    )
                )

        terms.sort(key=lambda trm: trm.title.lower())
        return SimpleVocabulary(terms)
