# coding: utf-8

from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ValidationError

from procu.api import models
from procu.api.common.fields import PaymentTermsField
from procu.api.enums import ES, QR, QS
from procu.api.supplier.serializers import SupplierBrief
from procu.rest import serializers
from procu.rest.fields import PKPrettyField
from .fields import DeadlineAt, QReasonField, QStatusField


class Log(serializers.ModelSerializer):
    supplier = SupplierBrief()
    status = QStatusField(name_only=True)
    reason = QReasonField(name_only=True)
    payment_terms = serializers.SerializerMethodField()  # deprecated field name

    @staticmethod
    def get_payment_terms(instance):
        return instance.terms.get('comment', '')

    class Meta:
        model = models.Quote
        fields = (
            'deadline_at',
            'payment_terms',
            'status',
            'reason',
            'supplier',
        )
        extra_kwargs = {'deadline_at': {'format': None}}


class Create(serializers.Serializer):
    suppliers = PKPrettyField(
        queryset=models.Supplier.objects.filter(is_deleted=False),
        serializer=SupplierBrief,
        allow_empty=False,
        label=_('QUOTES::SUPPLIERS'),
        many=True,
    )
    deadline_at = DeadlineAt(required=True, label=_('QUOTES::DEADLINE_AT'))

    @staticmethod
    def validate_deadline_at(value):
        if value < timezone.now():
            raise ValidationError(_('QUOTES::ERROR_DEADLINE_PASSED'))
        return value


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


class UpdateStatus(serializers.ModelSerializer):
    status = QStatusField(required=True)
    reason = QReasonField(required=False)

    def validate(self, data):
        status = data['status']
        reason = data['reason'] = data.get('reason', QR.NONE)

        user = self.context['request'].user

        if not self.instance.can_update_status(user, status, reason):
            raise ValidationError(_('QUOTES::ERROR_UNAVAILABLE_STATUS'))

        success = (
            (QS.CHECKOUT, QR.NONE),
            (QS.SHIPPED, QR.NONE),
            (QS.CLOSED, QR.DELIVERED),
        )

        data['has_won'] = (status, reason) in success

        return data

    class Meta:
        model = models.Quote
        fields = ('status', 'reason')


class Update(serializers.ModelSerializer):
    terms = PaymentTermsField()

    class Meta:
        model = models.Quote
        fields = ('deadline_at', 'delivery_at', 'terms')


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


class RequestSerializer(serializers.ModelSerializer):
    enquiry_id = serializers.PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = models.Request
        fields = ('enquiry_id', 'no_replacement')


class Retrieve(serializers.ModelSerializer):
    request = RequestSerializer()
    supplier = SupplierBrief()
    status = QStatusField()
    reason = QReasonField()
    hide_products = serializers.SerializerMethodField()
    invoices = serializers.SerializerMethodField()
    terms = PaymentTermsField()

    class Meta:
        model = models.Quote
        fields = (
            'id',
            'request',
            'supplier',
            'deadline_at',
            'created_at',
            'updated_at',
            'delivery_at',
            'terms',
            'status',
            'reason',
            'has_offer',
            'has_won',
            'hide_products',
            'invoices',
        )

    @staticmethod
    def get_hide_products(instance):
        return instance.status >= ES.CHECKOUT

    @staticmethod
    def get_invoices(instance):
        return (
            models.Invoice.objects.filter(
                enquiry_id=instance.request.enquiry_id,
                supplier_id=instance.supplier_id,
            )
            .values('id', 'created_at')
            .order_by('-created_at')
        )
