/*
    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 serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::BTreeMap;

#[derive(Debug, Serialize, Default)]
#[serde(rename_all = "PascalCase")]
pub(super) struct JellyfinItemsResponse {
    pub items: Vec<JellyfinItem>,
    pub total_record_count: usize,
    pub start_index: usize,
}

#[derive(Debug, Serialize, Deserialize)]
pub(super) enum JellyfinItemType {
    AudioBook,
    Movie,
    BoxSet,
    Book,
    Photo,
    PhotoAlbum,
    TvChannel,
    LiveTvProgram,
    Video,
    Audio,
    MusicAlbum,
    CollectionFolder,
}

#[derive(Debug, Clone, Serialize)]
pub(super) enum JellyfinMediaStreamType {
    Video,
    Audio,
    Subtitle,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "PascalCase")]
pub(super) struct JellyfinMediaStream {
    pub codec: String,
    pub time_base: String,
    pub video_range: String,
    pub video_range_type: String,
    pub audio_spatial_format: String,
    pub display_title: String,
    pub is_interlaced: bool,
    pub is_avc: bool,
    pub bit_rate: usize,
    pub bit_depth: usize,
    pub ref_frames: usize,
    pub is_default: bool,
    pub is_forced: bool,
    pub is_hearing_impaired: bool,
    pub height: Option<u64>,
    pub width: Option<u64>,
    pub average_frame_rate: Option<f64>,
    pub real_frame_rate: Option<f64>,
    pub reference_frame_rate: Option<f64>,
    pub profile: String,
    pub r#type: JellyfinMediaStreamType,
    pub aspect_ratio: String,
    pub index: usize,
    pub is_external: bool,
    pub is_text_subtitle_stream: bool,
    pub supports_external_stream: bool,
    pub pixel_format: String,
    pub level: usize,
    pub is_anamorphic: bool,
    pub channel_layout: Option<String>,
    pub channels: Option<usize>,
    pub sample_rate: Option<f64>,
    pub localized_default: String,
    pub localized_external: String,
}

#[derive(Debug, Clone, Serialize)]
pub(super) enum JellyfinMediaSourceProtocol {
    File,
}
#[derive(Debug, Clone, Serialize)]
pub(super) enum JellyfinMediaSourceType {
    Default,
}

#[derive(Debug, Clone, Serialize)]
pub(super) enum JellyfinVideoType {
    VideoFile,
}

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "PascalCase")]
pub(super) struct JellyfinMediaSource {
    pub protocol: JellyfinMediaSourceProtocol,
    pub id: String,
    pub path: String,
    pub r#type: JellyfinMediaSourceType,
    pub container: String,
    pub size: usize,
    pub name: String,
    pub is_remote: bool,
    pub e_tag: String,
    pub run_time_ticks: f64,
    pub read_at_native_framerate: bool,
    pub ignore_dts: bool,
    pub ignore_index: bool,
    pub gen_pts_input: bool,
    pub supports_transcoding: bool,
    pub supports_direct_stream: bool,
    pub supports_direct_play: bool,
    pub is_infinite_stream: bool,
    pub use_most_compatible_transcoding_profile: bool,
    pub requires_opening: bool,
    pub requires_closing: bool,
    pub requires_looping: bool,
    pub supports_probing: bool,
    pub video_type: JellyfinVideoType,
    pub media_streams: Vec<JellyfinMediaStream>,
    pub media_attachments: Vec<()>,
    pub formats: Vec<()>,
    pub bitrate: usize,
    pub required_http_headers: BTreeMap<(), ()>,
    pub transcoding_sub_protocol: String,
    pub default_audio_stream_index: usize,
    pub default_subtitle_stream_index: usize,
    pub has_segments: bool,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub(super) struct JellyfinItem {
    pub name: String,
    pub server_id: String,
    pub id: String,
    pub e_tag: String,
    pub date_created: String,
    pub can_delete: bool,
    pub can_download: bool,
    pub preferred_metadata_language: String,
    pub preferred_metadata_country_code: String,
    pub sort_name: String,
    pub forced_sort_name: String,
    pub external_urls: Vec<()>,
    pub enable_media_source_display: bool,
    pub custom_rating: String,
    pub channel_id: Option<String>,
    pub overview: String,
    pub taglines: Vec<String>,
    pub genres: Vec<()>,
    pub play_access: Option<String>,
    pub remote_trailers: Vec<()>,
    pub provider_ids: BTreeMap<(), ()>,
    pub is_folder: bool,
    pub parent_id: String,
    pub r#type: JellyfinItemType,
    pub people: Vec<JellyfinPerson>,
    pub studios: Vec<JellyfinStudio>,
    pub genre_items: Vec<()>,
    pub local_trailer_count: usize,
    pub special_feature_count: usize,
    pub child_count: usize,
    pub locked_fields: Vec<()>,
    pub lock_data: bool,
    pub tags: Vec<String>,
    pub user_data: Value,
    pub display_preferences_id: String,
    pub primary_image_aspect_ratio: f64,
    pub collection_type: String,
    pub image_tags: BTreeMap<String, String>,
    pub backdrop_image_tags: Vec<String>,
    pub location_type: Option<String>,
    pub media_type: String,
    pub video_type: Option<String>,
    pub container: Option<String>,
    pub run_time_ticks: Option<i64>,
    pub media_sources: Option<Vec<JellyfinMediaSource>>,
    pub media_streams: Option<Vec<JellyfinMediaStream>>,
    pub path: Option<String>,
}

#[derive(Debug, Serialize)]
pub(super) enum JellyfinPersonType {
    Actor,
    // Writer,
    // Producer,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub(super) struct JellyfinPerson {
    pub name: String,
    pub id: String,
    pub role: String,
    pub r#type: JellyfinPersonType,
    pub primary_image_tag: String,
}

#[derive(Debug, Serialize)]
#[serde(rename_all = "PascalCase")]
pub(super) struct JellyfinStudio {
    pub name: String,
    pub id: String,
}
