# coding: utf-8

import io
import logging

from rest_framework.exceptions import ParseError
from rest_framework.parsers import JSONParser

from procu.api import models
from procu.api.user.serializers import UserBrief
from procu.rest import serializers
from .constants import LOG_TYPES

logger = logging.getLogger(__name__)


class QuoteSerializer(serializers.ModelSerializer):

    supplier = serializers.CharField(source='supplier.title')

    class Meta:
        model = models.Quote
        fields = ('id', 'supplier')


class EnquirySerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Enquiry
        fields = ('id', 'subject')


class EnquiryProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.EnquiryProduct
        fields = ('id', 'name', 'qty')


class JSONField(serializers.ReadOnlyField):
    def to_representation(self, value):
        try:
            stream = io.BytesIO(value.encode('utf-8'))
            return JSONParser().parse(stream)
        except ValueError:
            return {}


class Log(serializers.ModelSerializer):

    user = UserBrief()

    enquiry = EnquirySerializer(allow_null=True)
    quote = QuoteSerializer(allow_null=True)

    diff = JSONField(source='data')
    old = JSONField()
    new = JSONField()

    description = serializers.SerializerMethodField()

    def to_representation(self, instance):
        try:
            return super().to_representation(instance)
        except ParseError:
            logger.exception('Error while rendering log event: %d', instance.id)

    class Meta:
        model = models.Log
        fields = (
            'id',
            'enquiry',
            'quote',
            'user',
            'type',
            'description',
            'happened_at',
            'new',
            'old',
            'diff',
        )

    @staticmethod
    def get_description(instance):
        return LOG_TYPES.get(instance.type, '')
