# coding: utf-8
from django.core import mail
from django.utils import timezone
from rest_framework.response import Response

from procu.api import enums, models
from procu.api.enquiry import serializers
from procu.api.enquiry.access.utils import give_access_to_user
from procu.api.push.internal import (
    notify_enquiry_assigned,
    notify_enquiry_created,
)
from procu.api.utils import json_dumps
from procu.rest import generics, permissions


class EnquiryClone(generics.GenericAPIView):
    permission_classes = (permissions.EntryPermission,)
    lookup_url_kwarg = 'enquiry_id'

    def get_queryset(self):
        return (
            models.Enquiry.objects.permitted(self.request.user)
            .select_related('draft')
            .prefetch_related('attachments')
        )

    def post(self, request, *args, **kwargs):

        enquiry = self.get_object()

        attachments = list(enquiry.attachments.all())
        access_list = list(
            a.user
            for a in enquiry.access.filter(
                sources__contains=[enums.ACCESS_SOURCE.ACCESS]
            )
        )

        # ----------------------------------------------------------------------

        draft = None
        rfx = None

        try:
            rfx = models.Request.objects.get(enquiry=enquiry)

        except models.Request.DoesNotExist:
            pass

        if rfx:
            # Copy request data to publishing draft.

            rfx_suppliers = rfx.quotes.values_list('supplier_id', flat=True)
            rfx_products = rfx.products.values('name', 'qty', 'comment')

            draft_attachments = [
                models.Attachment(author=request.user, **att)
                for att in rfx.attachments.values('filename', 'file')
            ]
            objs = models.Attachment.objects.bulk_create(draft_attachments)
            atts_ids = [obj.id for obj in objs]

            draft_data = {
                'subject': rfx.subject,
                'address': rfx.address_id,
                'legal_entity': rfx.legal_entity_id,
                'no_replacement': rfx.no_replacement,
                'description': rfx.description,
                'show_assignee': rfx.show_assignee,
                'suppliers': list(rfx_suppliers),
                'products': list(rfx_products),
                'attachments': atts_ids,
            }

            draft = models.FormData.objects.create(
                data=draft_data, author=request.user
            )

        elif enquiry.draft:
            # Preserve publishing draft when cloning from the DRAFT status

            draft = models.FormData.objects.create(
                data=enquiry.draft.data, author=request.user
            )

        # ----------------------------------------------------------------------

        old_key = enquiry.key

        enquiry.pk = enquiry.id = None
        enquiry.created_at = enquiry.updated_at = timezone.now()
        enquiry.status = enums.ES.DRAFT
        enquiry.reason = enums.ER.NONE
        enquiry.author = request.user
        enquiry.draft = draft

        enquiry.save()
        enquiry = models.Enquiry.objects.get(pk=enquiry.pk)

        models.Link.objects.create(
            author=request.user,
            enquiry=enquiry,
            type=enums.LINK.PROCU,
            key=old_key,
        )

        for attachment in attachments:
            attachment.pk = None
            attachment.author = self.request.user
            attachment.enquiry = enquiry
            attachment.request = None
            attachment.save()

        for user in access_list:
            give_access_to_user(enquiry.pk, user)

        enquiry.refresh_from_db()

        models.Log.objects.create(
            enquiry=enquiry,
            user=self.request.user,
            type='create_enquiry',
            new=json_dumps(serializers.Log(enquiry).data),
        )

        messages = []

        if enquiry.manager_id not in (None, request.user.id):
            messages.extend(notify_enquiry_assigned(enquiry.id, request.user))

        if enquiry.manager_id is None:
            messages.extend(
                notify_enquiry_created(enquiry.id, self.request.user)
            )

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

        return Response({'id': enquiry.id})
