from django.forms import widgets
from dynamic_preferences import types
from dynamic_preferences.registries import global_preferences_registry

music = types.Section("music")
quality_filters = types.Section("quality_filters")


@global_preferences_registry.register
class MaxTracks(types.BooleanPreference):
    show_in_api = True
    section = music
    name = "transcoding_enabled"
    verbose_name = "Transcoding enabled"
    help_text = (
        "Enable transcoding of audio files in formats requested by the client. "
        "This is especially useful for devices that do not support formats "
        "such as Flac or Ogg, but the transcoding process will increase the "
        "load on the server."
    )
    default = True


@global_preferences_registry.register
class MusicCacheDuration(types.IntPreference):
    show_in_api = True
    section = music
    name = "transcoding_cache_duration"
    default = 60 * 24 * 7
    verbose_name = "Transcoding cache duration"
    help_text = (
        "How many minutes do you want to keep a copy of transcoded tracks "
        "on the server? Transcoded files that were not listened in this interval "
        "will be erased and retranscoded on the next listening."
    )
    field_kwargs = {"required": False}


@global_preferences_registry.register
class MbidTaggedContent(types.BooleanPreference):
    show_in_api = True
    section = music
    name = "only_allow_musicbrainz_tagged_files"
    verbose_name = "Only allow Musicbrainz tagged files"
    help_text = (
        "Requires uploaded files to be tagged with a MusicBrainz ID. "
        "Enabling this setting has no impact on previously uploaded files. "
        "You can use the CLI to clear files that don't contain an MBID or "
        "or enable quality filtering to hide untagged content from API calls. "
    )
    default = False


@global_preferences_registry.register
class MbGenreTags(types.BooleanPreference):
    show_in_api = True
    section = music
    name = "musicbrainz_genre_update"
    verbose_name = "Prepopulate tags with MusicBrainz Genre "
    help_text = (
        "Will trigger a monthly update of the tag table "
        "using Musicbrainz genres. Non-existing tag will be created and "
        "MusicBrainz Ids will be added to the tags if "
        "they match the genre name."
    )
    default = True


@global_preferences_registry.register
class MbSyncTags(types.BooleanPreference):
    show_in_api = True
    section = music
    name = "sync_musicbrainz_tags"
    verbose_name = "Sync MusicBrainz to to funkwhale objects"
    help_text = (
        "If uploaded files are tagged with a MusicBrainz ID, "
        "Funkwhale will query MusicBrainz server to add tags to "
        "the track, artist and album objects."
    )
    default = False


# quality_filters section. Note that the default False is not applied in the fronted
# (the filter will onlyu be use if set to True)
@global_preferences_registry.register
class BitrateFilter(types.ChoicePreference):
    show_in_api = True
    section = quality_filters
    name = "bitrate_filter"
    verbose_name = "Upload Quality Filter"
    default = "low"
    choices = [
        ("low", "Allow all audio qualities"),
        ("medium", "Medium : Do not allow low quality"),
        ("high", "High : only allow high and very-high audio qualities"),
        ("very_high", "Very High : only allow very-high audio quality"),
    ]
    help_text = (
        "The main page content can be filtered based on audio quality. "
        "This will exclude lower quality, higher qualities are never excluded. "
        "Quality Table can be found in the docs."
    )
    field_kwargs = {"choices": choices, "required": False}


@global_preferences_registry.register
class HasMbid(types.BooleanPreference):
    show_in_api = True
    section = quality_filters
    name = "has_mbid"
    verbose_name = "Musicbrainz Ids filter"
    help_text = "Should we filter out metadata without Musicbrainz Ids ?"
    default = False


@global_preferences_registry.register
class Format(types.MultipleChoicePreference):
    show_in_api = True
    section = quality_filters
    name = "format"
    verbose_name = "Allowed Audio Format"
    default = (["aac", "aif", "aiff", "flac", "mp3", "ogg", "opus"],)
    choices = [
        ("ogg", "ogg"),
        ("opus", "opus"),
        ("flac", "flac"),
        ("aif", "aif"),
        ("aiff", "aiff"),
        ("aac", "aac"),
        ("mp3", "mp3"),
    ]
    help_text = "Witch audio format to allow"


@global_preferences_registry.register
class AlbumArt(types.BooleanPreference):
    show_in_api = True
    section = quality_filters
    name = "has_cover"
    verbose_name = "Album art Filter"
    help_text = "Only Albums with a cover will be displayed in the home page"
    default = False


@global_preferences_registry.register
class Tags(types.BooleanPreference):
    show_in_api = True
    section = quality_filters
    name = "has_tags"
    verbose_name = "Tags Filter"
    help_text = "Only content with at least one tag will be displayed"
    default = False


@global_preferences_registry.register
class ReleaseDate(types.BooleanPreference):
    show_in_api = True
    section = quality_filters
    name = "has_release_date"
    verbose_name = "Release date Filter"
    help_text = "Only content with a release date will be displayed"
    default = False


@global_preferences_registry.register
class JoinPhrases(types.StringPreference):
    show_in_api = True
    section = music
    name = "join_phrases"
    verbose_name = "Join Phrases"
    help_text = (
        "Used by the artist parser to create multiples artists in case the metadata "
        "is a single string. BE WARNED, changing the order or the values can break the parser in unexpected ways. "
        "It's MANDATORY to escape dots and to put doted variation before because the first match is used "
        r"(example : `|feat\.|ft\.|feat|` and not `feat|feat\.|ft\.|feat`.). ORDER is really important "
        "(says an anarchist). To avoid artist duplication and wrongly parsed artist data "
        "it's recommended to tag files with Musicbrainz Picard. "
    )
    default = (
        r"featuring | feat\. | ft\. | feat | with | and | & | vs\. | \| | \||\| |\|| , | ,|, |,|"
        r" ; | ;|; |;| versus | vs | \( | \(|\( |\(| Remix\) |Remix\) | Remix\)| \) | \)|\) |\)| x |"
        "accompanied by | alongside | together with | collaboration with | featuring special guest |"
        "joined by | joined with | featuring guest | introducing | accompanied by | performed by | performed with |"
        "performed by and | and | featuring | with | presenting | accompanied by | and special guest |"
        "featuring special guests | featuring and | featuring & | and featuring "
    )
    widget = widgets.Textarea
    field_kwargs = {"required": False}


@global_preferences_registry.register
class DefaultJoinPhrases(types.StringPreference):
    show_in_api = True
    section = music
    name = "default_join_phrase"
    verbose_name = "Default Join Phrase"
    help_text = (
        "The default join phrase used by artist parser"
        "For example: `artists = [artist1, Artist2]` will be displayed has : artist1.name, artis2.name"
        "Changing this value will not update already parsed artists"
    )
    default = ", "
    widget = widgets.Textarea
    field_kwargs = {"required": False}
