module Invidious::Videos
  extend self

  struct VideoPreferences
    include JSON::Serializable

    property annotations : Bool
    property preload : Bool
    property autoplay : Bool
    property comments : Array(String)
    property continue : Bool
    property continue_autoplay : Bool
    property controls : Bool
    property listen : Bool
    property local : Bool
    property preferred_captions : Array(String)
    property player_style : String
    property quality : String
    property quality_dash : String
    property raw : Bool
    property region : String?
    property related_videos : Bool
    property speed : Float32 | Float64
    property video_end : Float64 | Int32
    property video_loop : Bool
    property extend_desc : Bool
    property video_start : Float64 | Int32
    property volume : Int32
    property vr_mode : Bool
    property save_player_pos : Bool
  end

  def process_video_params(query, preferences)
    annotations = query["iv_load_policy"]?.try &.to_i?
    preload = query["preload"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    autoplay = query["autoplay"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    comments = query["comments"]?.try &.split(",").map(&.downcase)
    continue = query["continue"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    continue_autoplay = query["continue_autoplay"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    listen = query["listen"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    local = query["local"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    player_style = query["player_style"]?
    preferred_captions = query["subtitles"]?.try &.split(",").map(&.downcase)
    quality = query["quality"]?
    quality_dash = query["quality_dash"]?
    region = query["region"]?
    related_videos = query["related_videos"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    speed = query["speed"]?.try &.rchop("x").to_f?
    video_loop = query["loop"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    extend_desc = query["extend_desc"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    volume = query["volume"]?.try &.to_i?
    vr_mode = query["vr_mode"]?.try { |q| (q == "true" || q == "1").to_unsafe }
    save_player_pos = query["save_player_pos"]?.try { |q| (q == "true" || q == "1").to_unsafe }

    if preferences
      # region ||= preferences.region
      annotations ||= preferences.annotations.to_unsafe
      preload ||= preferences.preload.to_unsafe
      autoplay ||= preferences.autoplay.to_unsafe
      comments ||= preferences.comments
      continue ||= preferences.continue.to_unsafe
      continue_autoplay ||= preferences.continue_autoplay.to_unsafe
      listen ||= preferences.listen.to_unsafe
      local ||= preferences.local.to_unsafe
      player_style ||= preferences.player_style
      preferred_captions ||= preferences.captions
      quality ||= preferences.quality
      quality_dash ||= preferences.quality_dash
      related_videos ||= preferences.related_videos.to_unsafe
      speed ||= preferences.speed
      video_loop ||= preferences.video_loop.to_unsafe
      extend_desc ||= preferences.extend_desc.to_unsafe
      volume ||= preferences.volume
      vr_mode ||= preferences.vr_mode.to_unsafe
      save_player_pos ||= preferences.save_player_pos.to_unsafe
    end

    annotations ||= CONFIG.default_user_preferences.annotations.to_unsafe
    preload ||= CONFIG.default_user_preferences.preload.to_unsafe
    autoplay ||= CONFIG.default_user_preferences.autoplay.to_unsafe
    comments ||= CONFIG.default_user_preferences.comments
    continue ||= CONFIG.default_user_preferences.continue.to_unsafe
    continue_autoplay ||= CONFIG.default_user_preferences.continue_autoplay.to_unsafe
    listen ||= CONFIG.default_user_preferences.listen.to_unsafe
    local ||= CONFIG.default_user_preferences.local.to_unsafe
    player_style ||= CONFIG.default_user_preferences.player_style
    preferred_captions ||= CONFIG.default_user_preferences.captions
    quality ||= CONFIG.default_user_preferences.quality
    quality_dash ||= CONFIG.default_user_preferences.quality_dash
    related_videos ||= CONFIG.default_user_preferences.related_videos.to_unsafe
    speed ||= CONFIG.default_user_preferences.speed
    video_loop ||= CONFIG.default_user_preferences.video_loop.to_unsafe
    extend_desc ||= CONFIG.default_user_preferences.extend_desc.to_unsafe
    volume ||= CONFIG.default_user_preferences.volume
    vr_mode ||= CONFIG.default_user_preferences.vr_mode.to_unsafe
    save_player_pos ||= CONFIG.default_user_preferences.save_player_pos.to_unsafe

    annotations = annotations == 1
    preload = preload == 1
    autoplay = autoplay == 1
    continue = continue == 1
    continue_autoplay = continue_autoplay == 1
    listen = listen == 1
    local = local == 1
    related_videos = related_videos == 1
    video_loop = video_loop == 1
    extend_desc = extend_desc == 1
    vr_mode = vr_mode == 1
    save_player_pos = save_player_pos == 1

    if CONFIG.disabled?("dash") && quality == "dash"
      quality = "high"
    end

    if CONFIG.disabled?("local") && local
      local = false
    end

    if start = query["t"]? || query["time_continue"]? || query["start"]?
      video_start = decode_time(start)
    end
    video_start ||= 0

    if query["end"]?
      video_end = decode_time(query["end"])
    end
    video_end ||= -1

    raw = query["raw"]?.try &.to_i?
    raw ||= 0
    raw = raw == 1

    controls = query["controls"]?.try &.to_i?
    controls ||= 1
    controls = controls >= 1

    params = VideoPreferences.new({
      annotations:        annotations,
      preload:            preload,
      autoplay:           autoplay,
      comments:           comments,
      continue:           continue,
      continue_autoplay:  continue_autoplay,
      controls:           controls,
      listen:             listen,
      local:              local,
      player_style:       player_style,
      preferred_captions: preferred_captions,
      quality:            quality,
      quality_dash:       quality_dash,
      raw:                raw,
      region:             region,
      related_videos:     related_videos,
      speed:              speed,
      video_end:          video_end,
      video_loop:         video_loop,
      extend_desc:        extend_desc,
      video_start:        video_start,
      volume:             volume,
      vr_mode:            vr_mode,
      save_player_pos:    save_player_pos,
    })

    return params
  end
end
