from rest_framework import serializers
import time

from .models import Member, Project, Hub, Beacon, Unsync

import logging

logger = logging.getLogger(__name__)


class MemberSerializer(serializers.ModelSerializer):
    advertisement_project_id = serializers.ReadOnlyField(source='get_advertisement_project_id')
    project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all())

    class Meta:
        model = Member
        fields = ('id', 'project', 'advertisement_project_id', 'name', 'email', 'badge', 'observed_id', 'active', 'comments','last_seen_ts', 'last_audio_ts',
                  'last_audio_ts_fract', 'last_proximity_ts', 'last_contacted_ts', 'last_unsync_ts', 'last_voltage', 'key')
        read_only_fields = ('id','project','advertisement_project_id', 'key')

    def update(self, instance, validated_data):
        # instance is the current Member stored in the DB,
        # validated_data is the incoming data

        # if we have an older audio_ts, update it
        if validated_data.get('last_audio_ts') > instance.last_audio_ts:
            instance.last_audio_ts = validated_data.get('last_audio_ts',
                                                instance.last_audio_ts)
            instance.last_audio_ts_fract = validated_data.get('last_audio_ts_fract',
                                                instance.last_audio_ts_fract)

        # if we have an older proximity_ts, update it
        if validated_data.get('last_proximity_ts') > instance.last_proximity_ts:
            instance.last_proximity_ts = validated_data.get('last_proximity_ts', instance.last_proximity_ts)

        # if we have an older last_seen_ts, update it and voltage
        if validated_data.get('last_seen_ts') > instance.last_seen_ts:
            instance.last_seen_ts = validated_data.get('last_seen_ts', instance.last_seen_ts)
            instance.last_voltage = validated_data.get('last_voltage', instance.last_voltage)


        # if we have an older last_contacted_ts, update it
        if validated_data.get('last_contacted_ts') > instance.last_contacted_ts:
            instance.last_contacted_ts = validated_data.get('last_contacted_ts', instance.last_contacted_ts)

        # need to record all unsyncs
        # if this is not performant we can maintain both the last unsync 
        # in the member object as well as a separate table of unsync history
        if validated_data.get('last_unsync_ts') > instance.last_unsync_ts:
            # create an unsync obj to keep a history of all unsyncs
            Unsync.objects.create(
                    member=instance, 
                    unsync_ts=validated_data.get('last_unsync_ts', instance.last_unsync_ts))

            # save the latest ts in the member obj
            instance.last_unsync_ts = validated_data.get('last_unsync_ts', instance.last_unsync_ts)

        instance.observed_id = validated_data.get('observed_id', instance.observed_id)

        instance.save()
        return instance


class BeaconSerializer(serializers.ModelSerializer):
    advertisement_project_id = serializers.ReadOnlyField(source='get_advertisement_project_id')
    project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all())
    
    class Meta:
        model = Beacon
        fields = ('id','project', 'advertisement_project_id','name', 'badge', 'observed_id','active', 'comments',
         'last_seen_ts','last_voltage', 'key')
        read_only_fields = ('advertisement_project_id', 'id','project', 'key')

    def update(self, instance, validated_data):
        # if we have an older last_seen_ts, update it and voltage
        if validated_data.get('last_seen_ts') > instance.last_seen_ts:
            instance.last_seen_ts = validated_data.get('last_seen_ts', instance.last_seen_ts)
            instance.last_voltage = validated_data.get('last_voltage', instance.last_voltage)

        instance.observed_id = validated_data.get('observed_id', instance.observed_id)

        instance.save()
        return instance


class HubSerializer(serializers.ModelSerializer):
    project = serializers.PrimaryKeyRelatedField(queryset=Project.objects.all())

    class Meta:
        model = Hub
        fields = ('id', 'project', 'name', 'last_seen_ts',
                  'god', 'uuid', 'ip_address', 'key')
        read_only_fields = ('id', 'project', 'name',
                            'heartbeat', 'key', 'god', 'uuid')
