using System.Runtime.Serialization;
namespace Jellyfin.Plugin.SmartPlaylist {

    class GuidDeserializer {
        public static Guid deserialize(string v) {
            if (v.Length == 32) {
                return Guid.ParseExact(v, "N");
            }
            return Guid.Parse(v);
        }
    }

    [Serializable]
    public class SmartPlaylistLinkDto : ISerializable {
        public PlaylistId PlaylistId { get; set; }
        public UserId UserId { get; set; }

        public SmartPlaylistLinkDto() {
            PlaylistId = Guid.Empty;
            UserId = Guid.Empty;
        }

        protected SmartPlaylistLinkDto(SerializationInfo info, StreamingContext context) {
            if (info.GetValue("PlaylistId", typeof(PlaylistId)) is PlaylistId _PlaylistId) {
                PlaylistId = _PlaylistId;
            } else {
                PlaylistId = Guid.Empty;
            }
            if (info.GetValue("UserId", typeof(UserId)) is UserId _UserId) {
                UserId = _UserId;
            } else {
                UserId = Guid.Empty;
            }
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            info.AddValue("PlaylistId", PlaylistId);
            info.AddValue("UserId", UserId);
        }
    }

    [Serializable]
    public class SmartPlaylistDto : ISerializable {
        private static string DEFAULT_PROGRAM = "(begin (invoke item \"IsFavoriteOrLiked\" (list *user*)))";
        private static string DEFAULT_SORT_PROGRAM = "(begin *items*)";
        public SmartPlaylistId Id { get; set; }
        public SmartPlaylistLinkDto[] Playlists { get; set; }
        public string Name { get; set; }
        public string Program { get; set; }
        public string SortProgram { get; set; }
        public string? Filename { get; set; }
        public bool Enabled { get; set; }

        public SmartPlaylistDto() {
            Id = "";
            Playlists = [];
            Name = Id.ToString();
            Program = DEFAULT_PROGRAM;
            SortProgram = DEFAULT_SORT_PROGRAM;
            Filename = null;
            Enabled = true;
        }

        protected SmartPlaylistDto(SerializationInfo info, StreamingContext context) {
            if (info.GetValue("Id", typeof(SmartPlaylistId)) is SmartPlaylistId _Id) {
                Id = _Id;
            } else {
                Id = "";
            }
            if (info.GetValue("Playlists", typeof(SmartPlaylistLinkDto[])) is SmartPlaylistLinkDto[] _Playlists) {
                Playlists = _Playlists;
            } else {
                Playlists = [];
            }
            if (info.GetValue("Name", typeof(string)) is string _Name) {
                Name = _Name;
            } else {
                Name = Id.ToString();
            }
            if (info.GetValue("Program", typeof(string)) is string _Program) {
                Program = _Program;
            } else {
                Program = DEFAULT_PROGRAM;
            }
            if (info.GetValue("SortProgram", typeof(string)) is string _SortProgram) {
                SortProgram = _SortProgram;
            } else {
                SortProgram = DEFAULT_SORT_PROGRAM;
            }
            if (info.GetValue("Filename", typeof(string)) is string _Filename) {
                Filename = _Filename;
            } else {
                Filename = null;
            }
            if (info.GetValue("Enabled", typeof(bool)) is bool _Enabled) {
                Enabled = _Enabled;
            } else {
                Enabled = true;
            }
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            info.AddValue("Id", Id);
            info.AddValue("Playlists", Playlists);
            info.AddValue("Name", Name);
            info.AddValue("Program", Program);
            info.AddValue("Filename", Filename);
            info.AddValue("Enabled", Enabled);
        }
    }

    [Serializable]
    public class SmartCollectionDto {
        public SmartCollectionId Id { get; set; }
        public CollectionId CollectionId { get; set; }
        public string Name { get; set; }
        public string Program { get; set; }
        public string SortProgram { get; set; }
        public string? Filename { get; set; }
        public bool Enabled { get; set; }
    }
}