# coding: utf-8
from django.core import mail
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import gettext as _

from procu.api import models
from procu.api.attachment.serializers import AttachmentEntrySerializer
from procu.api.common.fields import UserBrief
from procu.api.push import external, internal
from procu.api.utils import json_dumps
from procu.rest.exceptions import ValidationError


def create_quote_comment(
    quote_id, user, data, attachment_ids=(), notify_from=None
):

    if (not user.is_staff) and (notify_from is not None):
        raise ValueError(
            "`notify_from` is invalid for comments from external users"
        )

    try:
        enquiry_id = models.Request.objects.values_list(
            'enquiry_id', flat=True
        ).get(quotes=quote_id)

    except ObjectDoesNotExist:
        raise ValueError("`quote_id` is invalid")

    if not (data.get('message') or attachment_ids):
        raise ValidationError({'message': _('COMMENTS::ERROR_BLANK_NO_FILES')})

    # ----------------------------------------------------------
    # Create

    kwargs = {'quote_id': quote_id, 'author_id': user.id, **data}

    comment = models.QuoteComment.objects.create(**kwargs)
    models.Attachment.objects.filter(
        author=user, id__in=attachment_ids, comment__isnull=True
    ).update(comment=comment)

    # ----------------------------------------------------------
    # Timeline

    log = {
        'id': comment.id,
        'author': UserBrief(user).data,
        'message': comment.message,
        'attachments': AttachmentEntrySerializer(
            comment.attachments, many=True
        ).data,
    }

    models.Log.objects.create(
        user=user,
        enquiry_id=enquiry_id,
        quote_id=quote_id,
        type='create_quote_comment',
        new=json_dumps(log),
    )

    # ----------------------------------------------------------
    # Notifications

    messages = internal.notify_quote_comment(comment.id, user)

    if user.is_staff:
        messages.extend(
            external.notify_quote_comment(comment.id, user, notify_from)
        )

    with mail.get_connection(fail_silently=True) as conn:
        conn.send_messages(messages)

    return comment
