import re

from rest_framework import serializers
from scrobbles.constants import Visibility
from scrobbles.models import (
    AudioScrobblerTSVImport,
    KoReaderImport,
    LastFmImport,
    Scrobble,
)


NOTE_POSITION_RE = re.compile(r"\[start:(\d+)\|end:(\d+)\]$")


class ScrobbleSerializer(serializers.HyperlinkedModelSerializer):
    note = serializers.CharField(required=False, allow_blank=True)
    note_position = serializers.DictField(required=False)

    class Meta:
        model = Scrobble
        fields = "__all__"

    def update(self, instance, validated_data):
        note = validated_data.pop("note", None)
        note_position = validated_data.pop("note_position", None)

        instance = super().update(instance, validated_data)

        if note is not None:
            log = instance.log or {}
            notes = log.get("notes", [])
            if isinstance(notes, str):
                notes = [notes]
            elif notes is None:
                notes = []

            if note_position:
                note = f"{note} [start:{note_position['start']}|end:{note_position['end']}]"

            notes.append(note)
            log["notes"] = notes
            instance.log = log
            instance.save(update_fields=["log"])

        return instance


def parse_note_position(note):
    match = NOTE_POSITION_RE.search(note)
    if match:
        start, end = match.groups()
        text = NOTE_POSITION_RE.sub("", note)
        return text, {"start": int(start), "end": int(end)}
    return note, None


class KoReaderImportSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = KoReaderImport
        fields = "__all__"


class AudioScrobblerTSVImportSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = AudioScrobblerTSVImport
        fields = "__all__"


class LastFmImportSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = LastFmImport
        fields = "__all__"
