/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2026 metamuffin <metamuffin.org>
*/

use super::A;
use jellycommon::{
    api::{FilterProperty, NodeFilterSort, SortOrder, SortProperty},
    user::{PlayerKind, Theme},
};
use rocket::{
    async_trait,
    form::{DataField, FromForm, FromFormField, Result, ValueField},
    UriDisplayQuery,
};

impl From<ANodeFilterSort> for NodeFilterSort {
    fn from(val: ANodeFilterSort) -> Self {
        NodeFilterSort {
            sort_by: val.sort_by.map(|e| match e {
                ASortProperty::ReleaseDate => SortProperty::ReleaseDate,
                ASortProperty::Title => SortProperty::Title,
                ASortProperty::Index => SortProperty::Index,
                ASortProperty::Duration => SortProperty::Duration,
                ASortProperty::RatingRottenTomatoes => SortProperty::RatingRottenTomatoes,
                ASortProperty::RatingMetacritic => SortProperty::RatingMetacritic,
                ASortProperty::RatingImdb => SortProperty::RatingImdb,
                ASortProperty::RatingTmdb => SortProperty::RatingTmdb,
                ASortProperty::RatingYoutubeViews => SortProperty::RatingYoutubeViews,
                ASortProperty::RatingYoutubeLikes => SortProperty::RatingYoutubeLikes,
                ASortProperty::RatingYoutubeFollowers => SortProperty::RatingYoutubeFollowers,
                ASortProperty::RatingUser => SortProperty::RatingUser,
                ASortProperty::RatingLikesDivViews => SortProperty::RatingLikesDivViews,
            }),
            filter_kind: val.filter_kind.map(|l| {
                l.into_iter()
                    .map(|e| match e {
                        AFilterProperty::FederationLocal => FilterProperty::FederationLocal,
                        AFilterProperty::FederationRemote => FilterProperty::FederationRemote,
                        AFilterProperty::Watched => FilterProperty::Watched,
                        AFilterProperty::Unwatched => FilterProperty::Unwatched,
                        AFilterProperty::WatchProgress => FilterProperty::WatchProgress,
                        AFilterProperty::KindMovie => FilterProperty::KindMovie,
                        AFilterProperty::KindVideo => FilterProperty::KindVideo,
                        AFilterProperty::KindShortFormVideo => FilterProperty::KindShortFormVideo,
                        AFilterProperty::KindMusic => FilterProperty::KindMusic,
                        AFilterProperty::KindCollection => FilterProperty::KindCollection,
                        AFilterProperty::KindChannel => FilterProperty::KindChannel,
                        AFilterProperty::KindShow => FilterProperty::KindShow,
                        AFilterProperty::KindSeries => FilterProperty::KindSeries,
                        AFilterProperty::KindSeason => FilterProperty::KindSeason,
                        AFilterProperty::KindEpisode => FilterProperty::KindEpisode,
                    })
                    .collect()
            }),
            sort_order: val.sort_order.map(|e| match e {
                ASortOrder::Ascending => SortOrder::Ascending,
                ASortOrder::Descending => SortOrder::Descending,
            }),
        }
    }
}

#[async_trait]
impl<'v> FromFormField<'v> for A<Theme> {
    fn from_value(field: ValueField<'v>) -> Result<'v, Self> {
        Err(field.unexpected())?
    }
    async fn from_data(field: DataField<'v, '_>) -> Result<'v, Self> {
        Err(field.unexpected())?
    }
}

#[async_trait]
impl<'v> FromFormField<'v> for A<PlayerKind> {
    fn from_value(field: ValueField<'v>) -> Result<'v, Self> {
        Err(field.unexpected())?
    }
    async fn from_data(field: DataField<'v, '_>) -> Result<'v, Self> {
        Err(field.unexpected())?
    }
}

#[derive(FromForm, UriDisplayQuery, Clone)]
pub struct ANodeFilterSort {
    sort_by: Option<ASortProperty>,
    filter_kind: Option<Vec<AFilterProperty>>,
    sort_order: Option<ASortOrder>,
}

#[derive(FromFormField, UriDisplayQuery, Clone)]
enum AFilterProperty {
    #[field(value = "fed_local")]
    FederationLocal,
    #[field(value = "fed_remote")]
    FederationRemote,
    #[field(value = "watched")]
    Watched,
    #[field(value = "unwatched")]
    Unwatched,
    #[field(value = "watch_progress")]
    WatchProgress,
    #[field(value = "kind_movie")]
    KindMovie,
    #[field(value = "kind_video")]
    KindVideo,
    #[field(value = "kind_short_form_video")]
    KindShortFormVideo,
    #[field(value = "kind_music")]
    KindMusic,
    #[field(value = "kind_collection")]
    KindCollection,
    #[field(value = "kind_channel")]
    KindChannel,
    #[field(value = "kind_show")]
    KindShow,
    #[field(value = "kind_series")]
    KindSeries,
    #[field(value = "kind_season")]
    KindSeason,
    #[field(value = "kind_episode")]
    KindEpisode,
}

#[derive(FromFormField, UriDisplayQuery, Clone)]
enum ASortProperty {
    #[field(value = "release_date")]
    ReleaseDate,
    #[field(value = "title")]
    Title,
    #[field(value = "index")]
    Index,
    #[field(value = "duration")]
    Duration,
    #[field(value = "rating_rt")]
    RatingRottenTomatoes,
    #[field(value = "rating_mc")]
    RatingMetacritic,
    #[field(value = "rating_imdb")]
    RatingImdb,
    #[field(value = "rating_tmdb")]
    RatingTmdb,
    #[field(value = "rating_yt_views")]
    RatingYoutubeViews,
    #[field(value = "rating_yt_likes")]
    RatingYoutubeLikes,
    #[field(value = "rating_yt_followers")]
    RatingYoutubeFollowers,
    #[field(value = "rating_user")]
    RatingUser,
    #[field(value = "rating_loved")]
    RatingLikesDivViews,
}

#[derive(FromFormField, UriDisplayQuery, Clone)]
enum ASortOrder {
    #[field(value = "ascending")]
    Ascending,
    #[field(value = "descending")]
    Descending,
}
