const view = window.view ??= {}
const app = window.app ??= {}

import * as mode from "./mode.js"
import * as queue from "./queue.js"
import * as entry from "./entry.js"

export const states = {
    EMPTY: 0,
    PLAYING: 1,
    PAUSED: 2
}

export const Init = () => {
    app.player = {
        currentTime: 0
    }
}

export const View = async () => {
    view.player = {
        cover: document.getElementById('track-cover'),
        title: document.getElementById('track-title'),
        artist: document.getElementById('track-artist'),
        timestamp: document.getElementById('timestamp'),
        trackLength: document.getElementById('track-length'),
        progress: document.getElementById('playback-progress')
    }

    if(app.player.current) {
        Switch(await Load(app.player.current, app.player.currentTime), app.player.current)
    }
}

export const Render = async () => {
    marqueeableText(view.player.title, app.player.current.name)
    marqueeableText(view.player.artist, app.player.current.artist)
    renderTimestamp()
    renderCover()
}

export const marqueeableText = (eElement, sName) => {    
    while(eElement.firstChild) {
        eElement.lastChild.remove()
    }
    eElement.classList = []
    let s = textContainer(eElement, sName)

    if(s.offsetWidth > eElement.offsetWidth) {
        eElement.classList = [ 'marquee' ]
        textContainer(eElement, sName)
    }
}

export const textContainer = (eElement, sText) => {
    let s = document.createElement('span')
    s.innerText = sText
    eElement.appendChild(s)
    return s
}

export const Open = () => {
    mode.Display('player')
    document.body.classList.add('paused')
}
    
export const OnKeydown = (event) => {
    switch(event.key) {
        case 'ArrowUp':
            navigator.volumeManager?.requestUp()
            break

        case 'ArrowDown':
            navigator.volumeManager?.requestDown()
            break
            
        case ' ':
        case 'Enter':
            if(State() === states.PLAYING) {
                Pause()
            } else {
                Play()
            }
            break

        case ']':
        case 'SoftRight':
            Next()
            break

        default:
            return true
    }
}

export const Load = async (eTrack, fromTime) => {
    let f = await device.Open(eTrack.handle)
    let u = URL.createObjectURL(f)

    // if(fromTime) {
    //     u = new URL(u)
    //     u.hash = '#t=' + fromTime
    // }
    let a = new Audio(u)
    if(fromTime) {
        a.currentTime = fromTime
    }

    return a
}

export const Switch = (aTrack, eTrack) => {
    if(State() === states.PLAYING) {
        view.playback.pause()
    }

    view.playback = aTrack
    app.player.current = eTrack
    attach()
    Render()
}

export const attach = () => {
    let a = view.playback

    a.addEventListener('playing', onStart)
    a.addEventListener('play', onPlay)
    a.addEventListener('pause', onPause)
    a.addEventListener('timeupdate', onTimeUpdate)
    a.addEventListener('ended', onEnded)

    storeTime()
}

export const onStart = () => {
    storeTime()
    renderDuration()
    onPlay()
    onTimeUpdate()
}

export const onPlay = () => {
}

export const onPause = () => {
}

export const onTimeUpdate = () => {
    let s = parseInt(view.playback.currentTime)
    if(s > app.player.currentTime) {
        storeTime()
        renderTimestamp()
    }
    renderProgress()
}

export const storeTime = () => {
    app.player.currentTime = view.playback ?
        parseInt(view.playback.currentTime) :
        0
}

export const formatTime = currentTime => {
	let minutes = Math.floor(currentTime / 60).toString()
	let seconds = Math.floor(currentTime % 60).toString()

	return minutes.padStart(2, '0') + ':' + seconds.padStart(2, '0')
}

export const renderProgress = () => {
    let t = view.playback.currentTime / view.playback.duration
    t = parseInt(t * 100)
    view.player.progress.style.strokeDasharray = `${t}, ${100 - t}`
}

export const onEnded = () => {
    view.playback = null
    Next()
}

export const renderTimestamp = (iTimestamp = app.player.currentTime) => {
    view.player.timestamp.innerText = formatTime(iTimestamp)
}

export const renderDuration = (iDuration = view.playback.duration) => {
    view.player.trackLength.innerText = formatTime(iDuration)
}

export const Play = async () => {
    if(view.playback) {
        view.playback.play()
        return
    }

    await Next()
}

export const Next = async () => {
    let e = queue.Shift()
    if(e) {
        Switch(await Load(e), e)
        view.playback.play()
    }
}

export const Pause = () => {
    view.playback.pause()
}

export const State = () => {
    if(view.playback == null) {
        return states.EMPTY
    } else {
        return view.playback.paused ? states.PAUSED : states.PLAYING
    }
}

export const renderCover = async () => {
    view.player.cover.src = app.player.current.coverId ?
        URL.createObjectURL(await entry.GetCover(app.player.current)):
        ''
}