local lvgl = require("lvgl")
local widgets = require("widgets")
local backstack = require("backstack")
local font = require("font")
local queue = require("queue")
local playing = require("playing")
local theme = require("theme")
local playback = require("playback")

local browser = {}

function browser.create(opts)
  local screen = {}
  screen.root = lvgl.Object(nil, {
    flex = {
      flex_direction = "column",
      flex_wrap = "wrap",
      justify_content = "flex-start",
      align_items = "flex-start",
      align_content = "flex-start",
    },
    w = lvgl.HOR_RES(),
    h = lvgl.VER_RES(),
  })
  screen.root:center()

  screen.status_bar = widgets.StatusBar(screen.root, {
    title = opts.title,
  })

  if opts.breadcrumb then
    local header = screen.root:Object {
      flex = {
        flex_direction = "column",
        flex_wrap = "wrap",
        justify_content = "flex-start",
        align_items = "flex-start",
        align_content = "flex-start",
      },
      w = lvgl.HOR_RES(),
      h = lvgl.SIZE_CONTENT,
      pad_left = 4,
      pad_right = 4,
      pad_bottom = 2,
      bg_opa = lvgl.OPA(100),
      bg_color = "#fafafa",
      scrollbar_mode = lvgl.SCROLLBAR_MODE.OFF,
    }

    header:Label {
      text = opts.breadcrumb,
      text_font = font.fusion_10,
    }

    local buttons = header:Object({
      flex = {
        flex_direction = "row",
        flex_wrap = "wrap",
        justify_content = "flex-end",
        align_items = "center",
        align_content = "center",
      },
      w = lvgl.PCT(100),
      h = lvgl.SIZE_CONTENT,
      pad_column = 4,
    })
    local original_iterator = opts.iterator:clone()
    local enqueue = widgets.IconBtn(buttons, "//lua/img/enqueue.png", "Enqueue")
    enqueue:onClicked(function()
      queue.add(original_iterator)
      playback.playing:set(true)
    end)
    -- enqueue:add_flag(lvgl.FLAG.HIDDEN)
    local play = widgets.IconBtn(buttons, "//lua/img/play_small.png", "Play")
    play:onClicked(function()
      queue.clear()
      queue.add(original_iterator)
      playback.playing:set(true)
      backstack.push(playing)
    end
    )
  end

  screen.list = lvgl.List(screen.root, {
    w = lvgl.PCT(100),
    h = lvgl.PCT(100),
    flex_grow = 1,
    scrollbar_mode = lvgl.SCROLLBAR_MODE.OFF,
  })

  local back = screen.list:add_btn(nil, "< Back")
  back:onClicked(backstack.pop)
  back:add_style(theme.list_item)

  screen.focused_item = 0
  screen.last_item = 0
  screen.add_item = function(item)
    if not item then return end
    screen.last_item = screen.last_item + 1
    local this_item = screen.last_item
    local btn = screen.list:add_btn(nil, tostring(item))
    btn:onClicked(function()
      local contents = item:contents()
      if type(contents) == "userdata" then
        backstack.push(function()
          return browser.create({
            title = opts.title,
            iterator = contents,
            breadcrumb = tostring(item),
          })
        end)
      else
        queue.clear()
        queue.add(contents)
        playback.playing:set(true)
        backstack.push(playing)
      end
    end)
    btn:onevent(lvgl.EVENT.FOCUSED, function()
      screen.focused_item = this_item
      if screen.last_item - 5 < this_item then
        screen.add_item(opts.iterator())
      end
    end)
    btn:add_style(theme.list_item)
  end

  for _ = 1, 8 do
    local val = opts.iterator()
    if not val then break end
    screen.add_item(val)
  end

  return screen
end

return browser.create
