import documents.models as document_models
from django.db import models
from django.utils.translation import gettext_lazy as _


class MailAccount(models.Model):
    class Meta:
        verbose_name = _("mail account")
        verbose_name_plural = _("mail accounts")

    class ImapSecurity(models.IntegerChoices):
        NONE = 1, _("No encryption")
        SSL = 2, _("Use SSL")
        STARTTLS = 3, _("Use STARTTLS")

    name = models.CharField(_("name"), max_length=256, unique=True)

    imap_server = models.CharField(_("IMAP server"), max_length=256)

    imap_port = models.IntegerField(
        _("IMAP port"),
        blank=True,
        null=True,
        help_text=_(
            "This is usually 143 for unencrypted and STARTTLS "
            "connections, and 993 for SSL connections.",
        ),
    )

    imap_security = models.PositiveIntegerField(
        _("IMAP security"),
        choices=ImapSecurity.choices,
        default=ImapSecurity.SSL,
    )

    username = models.CharField(_("username"), max_length=256)

    password = models.CharField(_("password"), max_length=256)

    character_set = models.CharField(
        _("character set"),
        max_length=256,
        default="UTF-8",
        help_text=_(
            "The character set to use when communicating with the "
            "mail server, such as 'UTF-8' or 'US-ASCII'.",
        ),
    )

    def __str__(self):
        return self.name


class MailRule(models.Model):
    class Meta:
        verbose_name = _("mail rule")
        verbose_name_plural = _("mail rules")

    class AttachmentProcessing(models.IntegerChoices):
        ATTACHMENTS_ONLY = 1, _("Only process attachments.")
        EVERYTHING = 2, _("Process all files, including 'inline' " "attachments.")

    class AttachmentAction(models.IntegerChoices):
        DELETE = 1, _("Mark as read, don't process read mails")
        MOVE = 2, _("Flag the mail, don't process flagged mails")
        MARK_READ = 3, _("Move to specified folder")
        FLAG = 4, _("Delete")

    class TitleSource(models.IntegerChoices):
        FROM_SUBJECT = 1, _("Use subject as title")
        FROM_FILENAME = 2, _("Use attachment filename as title")

    class CorrespondentSource(models.IntegerChoices):
        FROM_NOTHING = 1, _("Do not assign a correspondent")
        FROM_EMAIL = 2, _("Use mail address")
        FROM_NAME = 3, _("Use name (or mail address if not available)")
        FROM_CUSTOM = 4, _("Use correspondent selected below")

    name = models.CharField(_("name"), max_length=256, unique=True)

    order = models.IntegerField(_("order"), default=0)

    account = models.ForeignKey(
        MailAccount,
        related_name="rules",
        on_delete=models.CASCADE,
        verbose_name=_("account"),
    )

    folder = models.CharField(
        _("folder"),
        default="INBOX",
        max_length=256,
        help_text=_(
            "Subfolders must be separated by a delimiter, often a dot ('.') or"
            " slash ('/'), but it varies by mail server.",
        ),
    )

    filter_from = models.CharField(
        _("filter from"),
        max_length=256,
        null=True,
        blank=True,
    )
    filter_subject = models.CharField(
        _("filter subject"),
        max_length=256,
        null=True,
        blank=True,
    )
    filter_body = models.CharField(
        _("filter body"),
        max_length=256,
        null=True,
        blank=True,
    )

    filter_attachment_filename = models.CharField(
        _("filter attachment filename"),
        max_length=256,
        null=True,
        blank=True,
        help_text=_(
            "Only consume documents which entirely match this "
            "filename if specified. Wildcards such as *.pdf or "
            "*invoice* are allowed. Case insensitive.",
        ),
    )

    maximum_age = models.PositiveIntegerField(
        _("maximum age"),
        default=30,
        help_text=_("Specified in days."),
    )

    attachment_type = models.PositiveIntegerField(
        _("attachment type"),
        choices=AttachmentProcessing.choices,
        default=AttachmentProcessing.ATTACHMENTS_ONLY,
        help_text=_(
            "Inline attachments include embedded images, so it's best "
            "to combine this option with a filename filter.",
        ),
    )

    action = models.PositiveIntegerField(
        _("action"),
        choices=AttachmentAction.choices,
        default=AttachmentAction.MARK_READ,
    )

    action_parameter = models.CharField(
        _("action parameter"),
        max_length=256,
        blank=True,
        null=True,
        help_text=_(
            "Additional parameter for the action selected above, "
            "i.e., "
            "the target folder of the move to folder action. "
            "Subfolders must be separated by dots.",
        ),
    )

    assign_title_from = models.PositiveIntegerField(
        _("assign title from"),
        choices=TitleSource.choices,
        default=TitleSource.FROM_SUBJECT,
    )

    assign_tag = models.ForeignKey(
        document_models.Tag,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_("assign this tag"),
    )

    assign_document_type = models.ForeignKey(
        document_models.DocumentType,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_("assign this document type"),
    )

    assign_correspondent_from = models.PositiveIntegerField(
        _("assign correspondent from"),
        choices=CorrespondentSource.choices,
        default=CorrespondentSource.FROM_NOTHING,
    )

    assign_correspondent = models.ForeignKey(
        document_models.Correspondent,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        verbose_name=_("assign this correspondent"),
    )

    def __str__(self):
        return f"{self.account.name}.{self.name}"
