local JSON = require("./Infotainment/util/json")

RadioAppData = {
    countries = nil,
    stations = nil,
    selectedStation = nil,
    selectedCountry = nil,
    selectedColor = rgbm.new('#EF5261'),
    nowPlaying = {
        Artist = nil,
        Title = nil,
        Image = nil,
        Cache = false
    },
    openStationMenu = true,
    openCountryMenu = true,

    ---@type ui.MediaPlayer
    mediaPlayer = nil
}

function getNowPlaying(url)
    print(url)
    if (url ~= '') then
        web.get(url, nil, function(err, response)
            if (err) then
                print(err)
                return
            end
            if (response.status == 200) then
                -- print(JSON.parse(response.body).result[1].track_artist .. " - " .. JSON.parse(response.body).result[1].track_title)
                -- print(JSON.parse(response.body).result[1])
                if ((JSON.parse(response.body).result ~= nil) and JSON.parse(response.body).result[1] ~= nil) then
                    if (JSON.parse(response.body).result[1].track_artist ~= '') then
                        RadioAppData.nowPlaying.Artist = JSON.parse(response.body).result[1].track_artist
                    else
                        RadioAppData.nowPlaying.Artist = nil
                    end

                    if (JSON.parse(response.body).result[1].track_title ~= '') then
                        RadioAppData.nowPlaying.Title = JSON.parse(response.body).result[1].track_title
                    else
                        RadioAppData.nowPlaying.Title = nil
                    end
                    if (JSON.parse(response.body).result[1].track_image ~= '') then
                        RadioAppData.nowPlaying.Image = JSON.parse(response.body).result[1].track_image
                    else
                        RadioAppData.nowPlaying.Image = nil
                    end
                elseif ((JSON.parse(response.body).data ~= nil) and JSON.parse(response.body).data[1] ~= nil) then
                    if (JSON.parse(response.body).data[1].titles.primary ~= '') then
                        RadioAppData.nowPlaying.Artist = JSON.parse(response.body).data[1].titles.primary
                    else
                        RadioAppData.nowPlaying.Artist = nil
                    end

                    if (JSON.parse(response.body).data[1].titles.primary ~= '') then
                        RadioAppData.nowPlaying.Title = JSON.parse(response.body).data[1].titles.secondary
                    else
                        RadioAppData.nowPlaying.Title = nil
                    end
                    if (JSON.parse(response.body).data[1].image_url ~= '') then
                        -- RadioAppData.nowPlaying.Image = JSON.parse(response.body).data[1].image_url
                        RadioAppData.nowPlaying.Image = nil
                    else
                        RadioAppData.nowPlaying.Image = nil
                    end
                elseif ((JSON.parse(response.body).data ~= nil) and JSON.parse(response.body).data[1] ~= nil) then
                    if (JSON.parse(response.body).data[1].titles.primary ~= '') then
                        RadioAppData.nowPlaying.Artist = JSON.parse(response.body).data[1].titles.primary
                    else
                        RadioAppData.nowPlaying.Artist = nil
                    end

                    if (JSON.parse(response.body).data[1].titles.primary ~= '') then
                        RadioAppData.nowPlaying.Title = JSON.parse(response.body).data[1].titles.secondary
                    else
                        RadioAppData.nowPlaying.Title = nil
                    end
                    if (JSON.parse(response.body).data[1].image_url ~= '') then
                        -- RadioAppData.nowPlaying.Image = JSON.parse(response.body).data[1].image_url
                        RadioAppData.nowPlaying.Image = nil
                    else
                        RadioAppData.nowPlaying.Image = nil
                    end
                elseif ((JSON.parse(response.body).title ~= nil)) then
                    local convertedstring = split(JSON.parse(response.body).title, ' - ')
                    local t = ''
                    local a = ''
                    local breakindex = 0
                    for i = 1, table.getn(convertedstring), 1 do
                        if (convertedstring[i] == '-') then
                            breakindex = i + 1
                            break
                        end
                        if (a == '') then
                            a = convertedstring[i]
                        else
                            a = a .. " " .. convertedstring[i]
                        end
                    end
                    for i = breakindex, table.getn(convertedstring), 1 do
                        if (convertedstring[i] == '-') then
                            break
                        end
                        if (t == '') then
                            t = convertedstring[i]
                        else
                            t = t .. " " .. convertedstring[i]
                        end
                    end
                    if (a ~= '') then
                        RadioAppData.nowPlaying.Artist = a
                    else
                        RadioAppData.nowPlaying.Artist = nil
                    end

                    if (t ~= '') then
                        RadioAppData.nowPlaying.Title = t
                    else
                        RadioAppData.nowPlaying.Title = nil
                    end
                    --  if (JSON.parse(response.body).imageRef ~= '') then
                    -- RadioAppData.nowPlaying.Image = JSON.parse(res.body).base64image
                    RadioAppData.nowPlaying.Image = nil
                    -- else
                    --      RadioAppData.nowPlaying.Image = ''
                    -- end
                end
                -- print(radio)
                -- radio.stationsList = (JSON.parse(response.body).result)
                -- radio.station = radio.stationsList[3]
            else
                -- radio.stationsList = nil
                -- radio.station = nil
            end
        end)
        if (RadioAppData.nowPlaying.Image ~= nil) then
            web.get(RadioAppData.nowPlaying.Image, nil, function(errr, res)
                if (errr) then
                    print(errr)
                    return
                end
                if (res.status ~= 200) then
                    RadioAppData.nowPlaying.Image = nil
                end
            end)
        end
    end
end

function RadioAppData:playToggle()
    if self.mediaPlayer:playing() then
        self.mediaPlayer:pause()
    else
        self.mediaPlayer:play()
    end
end

function RadioAppData:selectStation(station)
    if type(station) == 'number' then
        local curIndex = table.indexOf(self.stations, self.selectedStation)
        return self:selectStation(self.stations[(#self.stations + curIndex - 1 + station) % #self.stations + 1])
    end
    if self.selectedStation == station then
        return
    end
    self.selectedStation = station
    print(self.nowPlaying.Artist)
    self.nowPlaying.Artist = nil
    self.nowPlaying.Title = nil
    self.nowPlaying.Image = nil
    if not self.mediaPlayer then
        self.mediaPlayer = ui.MediaPlayer():setAutoPlay(true)
        touchscreen.syncVolume(self.mediaPlayer)
    end
    self.mediaPlayer:setSource(station and station.streamURL)
end

local transition = touchscreen.createTransition(0.85)
local padding = system.narrowMode and 80 or 160

local function step(v)
    return (math.floor(v / 2) + math.smoothstep(math.min(v % 2, 1)))
end

local function time(value)
    if value == -1 then
        return '--:--'
    end
    return string.format('%02d:%02d', math.floor(value / 60), math.floor(value % 60))
end

local progressBaseColor = rgbm(33 / 255, 212 / 255, 94 / 255, 1)
local blurredBg = ui.ExtraCanvas(64)
local progressCurColor = progressBaseColor
local bgColor = rgbm(0, 0, 0, 1)
local coverColor1 = rgbm(0, 0, 0, 0.2)
local coverColor2 = rgbm(0, 0, 0, 1)

local function updateCover()
    local p = RadioAppData.nowPlaying.Image or RadioAppData.selectedStation.thumbnailSquare
    if p then
        blurredBg:update(function(dt)
            ui.beginBlurring()
            ui.drawImage(p, 0, ui.windowSize())
            ui.endBlurring(0.05)
        end)

        blurredBg:accessData(function(err, data)
            local c = rgbm()
            progressCurColor = rgbm()
            for y = 1, 3 do
                for x = 1, 3 do
                    progressCurColor:add(data:colorTo(c, 16 * x, 16 * y))
                end
            end
            progressCurColor:scale(1 / progressCurColor.mult)
            local h = progressCurColor.rgb:hsv()
            h.v = 1
            h.s = math.min(h.s * 1.3, 1)
            progressCurColor.rgb:set(h:rgb())

            bgColor.rgb:set(progressCurColor.rgb):scale(0.01)
            coverColor2.rgb:set(progressCurColor.rgb):scale(0.01)
        end)
    else
        blurredBg:clear(rgbm.colors.transparent)
        progressCurColor = progressBaseColor
    end
end

function updatePlayer()
    updateCover()
    touchscreen.syncVolumeIfFresh(RadioAppData.mediaPlayer)
    -- local playing = ac.currentlyPlaying()
    local p = math.min(ui.windowWidth() / 2, ui.windowHeight() * 1.2)
    local x = p - 300
    local y = (ui.windowHeight() - 240) / 2

    ui.drawRectFilled(0, ui.windowSize(), bgColor)
    ui.beginBlurring()
    ui.drawImage(blurredBg, -80, ui.windowHeight() + 80)
    ui.endBlurring(0.03)
    ui.drawRectFilledMultiColor(-80, ui.windowHeight() + 80, coverColor1, coverColor2, coverColor2, coverColor1)

    ui.setCursor(vec2(x, y))
    ui.image(RadioAppData.nowPlaying.Image or RadioAppData.selectedStation.thumbnailSquare, 180)

    ui.setCursor(vec2(x + 160 + 34, y - 10))
    if not RadioAppData.mediaPlayer:playing() then
        ui.pushStyleVarAlpha(0.5)
    end
    if(not RadioAppData.nowPlaying.Title) then
      ui.dwriteTextAligned(RadioAppData.selectedStation.title,
      system.adjustTextSize(RadioAppData.selectedStation.title, 50,
          ui.windowWidth() - (x + 160 + 34)), ui.Alignment.Start, ui.Alignment.Center,
      vec2(ui.windowWidth() - (x + 160 + 34), 75))
    else
    
    -- ui.dwriteTextWrapped(RadioAppData.nowPlaying.Title ~= '' and RadioAppData.nowPlaying.Title or 'Nothing', 35)
    ui.dwriteTextAligned(RadioAppData.nowPlaying.Title,
        system.adjustTextSize(RadioAppData.nowPlaying.Title, 35,
            ui.windowWidth() - (x + 160 + 34)), ui.Alignment.Start, ui.Alignment.Center,
        vec2(ui.windowWidth() - (x + 160 + 34), 50))
    if not RadioAppData.mediaPlayer:playing() then
        ui.popStyleVar()
    else
        ui.setCursor(vec2(x + 160 + 34, y + 40 + 15))
        ui.dwriteTextAligned(RadioAppData.nowPlaying.Artist, system.adjustTextSize(RadioAppData.nowPlaying.Artist, 25,
            ui.windowWidth() - (x + 160 + 34)), ui.Alignment.Start, ui.Alignment.Center,
            vec2(ui.windowWidth() - (x + 160 + 34), 35))
        -- ui.dwriteText(RadioAppData.nowPlaying.Artist, 25)

        ui.setCursor(vec2(x + 160 + 34, y + 75 + 30))
        -- ui.dwriteText(RadioAppData.selectedStation.title, 25)
        ui.dwriteTextAligned(RadioAppData.selectedStation.title, system.adjustTextSize(
            RadioAppData.selectedStation.title, 25, ui.windowWidth() - (x + 160 + 34)), ui.Alignment.Start,
            ui.Alignment.Center, vec2(ui.windowWidth() - (x + 160 + 34), 35))
    end
  end
    ui.setCursor(vec2(p - 105 - 30, y + 182))
    if touchscreen.iconButton(ui.Icons.Back, 60) then
        RadioAppData:selectStation(-1)
    end

    ui.setCursor(vec2(p - 0 - 30, y + 182))
    if touchscreen.iconButton(RadioAppData.mediaPlayer:playing() and ui.Icons.Pause or ui.Icons.Play, 60) then
        RadioAppData:playToggle()
    end

    ui.drawCircle(vec2(p, y + 200 + 12), 36, rgbm.colors.gray, 30, 2)

    ui.setCursor(vec2(p + 105 - 30, y + 182))
    if touchscreen.iconButton(ui.Icons.Next, 60) then
        RadioAppData:selectStation(1)
    end

    ui.setCursor(vec2(p + 210 - 30, y + 182))
    if touchscreen.iconButton(ui.Icons.Settings, 60) then
        RadioAppData.openStationMenu = true
    end

    touchscreen.volumeControl(vec2(0,11))
    system.transparentTopBar()
end

return function(dt)
    if not RadioAppData.countries then
        RadioAppData.countries = JSON.parse(io.load(io.relative('radio.json'))).Countries
        -- RadioAppData.stations = table.filter(table.map(io.load(io.relative('stations.txt')):split('\n'), function (line)
        -- if #line == 0 then return {} end
        --  return table.map(string.split(line, '#', 2)[1]:split('='), string.trim)
        --   end), function (line) return #line == 2 end)
    end
    if not RadioAppData.stations then
        RadioAppData.stations = RadioAppData.countries[1].Radios
    end

    if RadioAppData.mediaPlayer then
        if ((RadioAppData.nowPlaying.Cache == false) and (math.fmod(math.floor(os.clock()), 5) == 0)) then
            RadioAppData.nowPlaying.Cache = true
            getNowPlaying(RadioAppData.selectedStation.nowPlayingJson)
        else
            RadioAppData.nowPlaying.Cache = false
        end
    end

    if (not RadioAppData.openStationMenu) then
        updatePlayer()

    else
        ui.childWindow('stationsList', vec2(400, ui.availableSpaceY()), function()
            ui.offsetCursorY(40)
            ui.indent(padding)
            if(RadioAppData.selectedCountry == nil) then
                for i = 1, #RadioAppData.countries do
                    local s = RadioAppData.countries[i]
                    ui.dwriteText(s.Country, 20,
                        RadioAppData.selectedCountry == i and RadioAppData.selectedColor or rgbm.colors.white)
                    if touchscreen.itemTapped() then
                        RadioAppData.selectedCountry = i
                    end
                end
            else
                for i = 1, #RadioAppData.countries[RadioAppData.selectedCountry].Radios do
                    local s = RadioAppData.countries[RadioAppData.selectedCountry].Radios[i]
                    ui.dwriteText(s.title, 20,
                        RadioAppData.selectedStation == s and RadioAppData.selectedColor or rgbm.colors.white)
                    if touchscreen.itemTapped() then
                        RadioAppData:selectStation(s)
                        RadioAppData.selectedCountry = nil
                    end
                end
            end
            ui.unindent(padding)
            ui.offsetCursorY(40)
            system.scrolling(dt)
        end)

        if not RadioAppData.mediaPlayer then
            return
        end

        local tr = transition(dt, true)
        touchscreen.syncVolumeIfFresh(RadioAppData.mediaPlayer)

        ui.pushStyleVarAlpha(tr)
        local playerX = math.max(padding + 240, ui.windowWidth() * 0.45)
        ui.setCursor(vec2(playerX + 200 * (1 - tr), 0))
        ui.childWindow('player', vec2(400, ui.windowHeight()), function()

            ui.offsetCursorY(80)
            ui.dwriteText('Now playing:', 12)
            ui.dwriteText(RadioAppData.selectedStation.title, 30)
            ui.dwriteText(RadioAppData.selectedStation.streamURL, 12, rgbm.colors.gray)

            local p = 140 / 1.3
            local y = 40
            ui.setCursor(vec2(p - 105 / 1.3 - 30, y + 182))
            if touchscreen.iconButton(ui.Icons.Back, 60) then
                RadioAppData:selectStation(-1)
            end
            ui.setCursor(vec2(p - 0 - 30, y + 182))
            if touchscreen.iconButton(RadioAppData.mediaPlayer:playing() and ui.Icons.Pause or ui.Icons.Play, 60) then
                RadioAppData:playToggle()
            end
            if not RadioAppData.mediaPlayer:hasAudio() then
                local c = vec2(p, y + 200 + 12)
                ui.drawCircle(c, 36, rgbm.colors.gray, 30, 2)

                local t = ui.time()
                ui.pathArcTo(c, 36, step(t * 1.3 + 1) * 4.5 + t * 3, step(t * 1.3) * 4.5 + 5 + t * 3, 40)
                ui.pathStroke(RadioAppData.selectedColor, false, 2)
            else
                ui.drawCircle(vec2(p, y + 200 + 12), 36, RadioAppData.selectedColor, 30, 2)
            end
            ui.setCursor(vec2(p + 105 / 1.3 - 30, y + 182))
            if touchscreen.iconButton(ui.Icons.Next, 60) then
                RadioAppData:selectStation(1)
            end

            ui.setCursor(vec2(p + 210 / 1.35 - 30, y + 182))
            if touchscreen.iconButton(ui.Icons.Preview, 60) then
                RadioAppData.openStationMenu = false
            end
        end)

        touchscreen.volumeControl()
        ui.popStyleVar()
    end

end
