local just = require("just")
local spherefonts = require("sphere.assets.fonts")
local imgui = require("imgui")
local Fraction = require("ncdk.Fraction")
local gfx_util = require("gfx_util")

local Layout = require("ui.views.EditorView.Layout")

local tabs = {}

---@param t number
---@return string
local function to_ms(t)
	return math.floor(t * 1000) .. "ms"
end

---@param self table
function tabs.info(self)
	local md = self.game.editorModel.chart.chartmeta

	imgui.setSize(400, 1080, 400, 55)
	imgui.text("Chart info")
	md.title = imgui.input("title input", md.title, "title")
	md.artist = imgui.input("artist input", md.artist, "artist")
	md.source = imgui.input("source input", md.source, "source")
	md.tags = imgui.input("tags input", md.tags, "tags")
	md.name = imgui.input("name input", md.name, "name")
	md.creator = imgui.input("creator input", md.creator, "creator")
	md.level = imgui.input("level input", md.level, "level")
	md.audio_path = imgui.input("audio_path input", md.audio_path, "audio_path")
	md.background_path = imgui.input("background_path input", md.background_path, "background_path")
	md.preview_time = imgui.input("preview_time input", md.preview_time, "preview_time")
	md.tempo = imgui.input("tempo input", md.tempo, "tempo")
	md.inputmode = imgui.input("inputmode input", md.inputmode, "inputmode")

	imgui.separator()

	if imgui.button("save btn", "save") then
		self.game.editorController:save()
	end
	just.sameline()
	if imgui.button("save to osu btn", "save to osu") then
		self.game.editorController:saveToOsu()
	end
	if imgui.button("save to nanochart btn", "save to nanochart") then
		self.game.editorController:saveToNanoChart()
	end

	love.graphics.push("all")
	love.graphics.setColor(1, 1, 1, 0.75)
	love.graphics.setFont(spherefonts.get("Noto Sans", 36))
	imgui.text("The editor")
	imgui.text("is in development")
	love.graphics.pop()
end

---@param self table
function tabs.audio(self)
	local editorModel = self.game.editorModel

	local playing = 0
	for _ in pairs(editorModel.audioManager.sources) do
		playing = playing + 1
	end
	imgui.text("playing sounds: " .. playing)
	imgui.text("offsync: " .. to_ms(editorModel.timer:getAudioOffsync() or 0))

	local settings = self.game.configModel.configs.settings
	local a = settings.audio
	local v = a.volume
	if a.volumeType == "linear" then
		v.master = imgui.slider1("v.master", v.master, "%0.2f", 0, 1, 0.01, "master")
		v.music = imgui.slider1("v.music", v.music, "%0.2f", 0, 1, 0.01, "music")
		v.effects = imgui.slider1("v.effects", v.effects, "%0.2f", 0, 1, 0.01, "effects")
		v.metronome = imgui.slider1("v.metronome", v.metronome, "%0.2f", 0, 1, 0.01, "metronome")
	elseif a.volumeType == "logarithmic" then
		local logk = 20 / math.log(10)
		v.master = imgui.logslider("v.master", v.master, "%ddB", -60, 0, 1, logk, "master")
		v.music = imgui.logslider("v.music", v.music, "%ddB", -60, 0, 1, logk, "music")
		v.effects = imgui.logslider("v.effects", v.effects, "%ddB", -60, 0, 1, logk, "effects")
		v.metronome = imgui.logslider("v.metronome", v.metronome, "%ddB", -60, 0, 1, logk, "metronome")
	end

	imgui.separator()
	local mode = a.mode
	imgui.text("audio modes")
	imgui.text("primary: " .. mode.primary)
	imgui.text("secondary: " .. mode.secondary)

	imgui.separator()

	local ed = settings.editor
	ed.audioOffset = imgui.slider1("ed.audioOffset", ed.audioOffset * 1000, "%dms", -200, 200, 1, "main audio offset") / 1000
	ed.waveformOffset = imgui.slider1("ed.waveformOffset", ed.waveformOffset * 1000, "%dms", -200, 200, 1, "waveform offset") / 1000

	imgui.separator()
	imgui.text("waveform")
	local wf = self.game.configModel.configs.settings.editor.waveform
	wf.opacity = imgui.slider1("wf.opacity", wf.opacity, "%0.2f", 0, 1, 0.01, "opacity")
	wf.scale = imgui.slider1("wf.scale", wf.scale, "%0.2f", 0, 1, 0.01, "scale")

	imgui.separator()
	local md = self.game.editorModel.chart.chartmeta
	if imgui.button("set as preview", "set this moment as a preview") then
		md.preview_time = editorModel.point.absoluteTime
	end
end

local velocity = "1"
local expand = {"0", "1"}

---@param self table
function tabs.timings(self)
	local editorModel = self.game.editorModel
	local editor = self.game.configModel.configs.settings.editor
	local layer = editorModel.layer

	local dtp = editorModel.point

	if imgui.button("prev tp", "<") and dtp.prev then
		editorModel.scroller:scrollTimePoint(dtp.prev)
	end
	just.sameline()
	if imgui.button("next tp", ">") and dtp.next then
		editorModel.scroller:scrollTimePoint(dtp.next)
	end
	just.sameline()
	imgui.label("dtp label", tostring(dtp))

	editor.showTimings = imgui.checkbox("show timings", editor.showTimings, "show timings")

	if imgui.button("ncbt", "detect tempo and offset") then
		editorModel:detectTempoOffset()
	end
	if editorModel.ncbtContext.tempo then
		just.sameline()
		if imgui.button("ncbt apply", "apply") then
			editorModel:applyTempoOffset()
		end
	end

	imgui.separator()

	local interval = dtp._interval
	local intervalManager = editorModel.intervalManager

	if dtp.interval then
		imgui.text("Tempo: " .. dtp.interval:getTempo() .. " bpm")
	end

	if not intervalManager:isGrabbed() then
		if not interval then
			if imgui.button("split button", "split") then
				intervalManager:split(dtp)
			end
		elseif imgui.button("grab interval button", "grab") then
			intervalManager:grab(interval)
		end
	else
		if imgui.button("drop interval button", "drop") then
			intervalManager:drop()
		end
	end
	if interval and not intervalManager:isGrabbed() then
		just.sameline()
		if imgui.button("merge interval button", "merge") then
			intervalManager:merge(interval.point)
			editorModel.scroller:scrollSecondsDelta(0)
		end
		local beats = interval.beats
		local newBeats = imgui.intButtons("update interval", beats, 1, "beats")
		if beats ~= newBeats then
			intervalManager:update(interval, newBeats)
		end
	end

	imgui.separator()

	local totalBeats, avgBeatDuration = editorModel:getTotalBeats()
	imgui.text("Total beats: " .. totalBeats)
	imgui.text("Average tempo: " .. 60 / avgBeatDuration .. " bpm")

	imgui.separator()

	do return end

	just.row(true)
	velocity = imgui.input("velocity input", velocity, "velocity")
	if imgui.button("add velocity button", "add") then
		layer:getVelocityData(dtp, tonumber(velocity))
	end

	just.row(true)
	expand[1] = imgui.input("expand n input", expand[1])
	imgui.unindent()
	imgui.label("/ label", "/")
	expand[2] = imgui.input("expand d input", expand[2], "expand")
	if imgui.button("add expand button", "add") then
		layer:getExpandData(dtp, Fraction(tonumber(expand[1]), tonumber(expand[2])))
	end

	just.row()

	if dtp._velocityData then
		imgui.label("velocity label", "Velocity: " .. dtp._velocityData.currentSpeed .. " x")
		just.sameline()
		if imgui.button("remove velocity button", "remove") then
			layer:removeVelocityData(dtp)
		end
	end
	if dtp._expandData then
		imgui.label("expand label", "Expand: " .. dtp._expandData.duration .. " beats")
		just.sameline()
		if imgui.button("remove expand button", "remove") then
			layer:removeExpandData(dtp)
		end
	end
end

local qwerty = "qwerty"

---@param self table
function tabs.notes(self)
	local editorModel = self.game.editorModel
	local editor = self.game.configModel.configs.settings.editor

	local logSpeed = imgui.slider1("editor speed", editorModel:getLogSpeed(), "%d", -30, 50, 1, "speed")
	if logSpeed ~= editorModel:getLogSpeed() then
		editorModel:setLogSpeed(logSpeed)
	end
	editor.snap = imgui.slider1("snap select", editor.snap, "%d", 1, 16, 1, "snap")
	editor.lockSnap = imgui.checkbox("lock snap", editor.lockSnap, "lock snap")
	editor.tool = imgui.combo("tool select", editor.tool, editorModel.tools, nil, "tool")
	imgui.text("Use qwer to select tool")

	for i = 1, #editorModel.tools do
		if just.keypressed(qwerty:sub(i, i)) then
			editor.tool = editorModel.tools[i]
		end
	end

	if imgui.button("changeType", "change type") then
		editorModel.noteManager:changeType()
	end
end

return function(self)
	local editorModel = self.game.editorModel
	local w, h = Layout:move("base")

	love.graphics.setColor(1, 1, 1, 1)
	love.graphics.setFont(spherefonts.get("Noto Sans", 24))
	love.graphics.setLineStyle("smooth")

	local lineHeight = 55
	imgui.setSize(400, h, 200, lineHeight)
	love.graphics.setColor(1, 1, 1, 1)

	editorModel.state = imgui.tabs("editor overlay tabs", editorModel.state, editorModel.states)
	love.graphics.setColor(1, 1, 1, 1)
	imgui.setSize(400, h, 200, lineHeight)
	tabs[editorModel.state](self)

	if not editorModel.resourcesLoaded then
		w, h = Layout:move("base")
		love.graphics.setColor(1, 1, 1, 0.5)
		love.graphics.setFont(spherefonts.get("Noto Sans", 160))
		gfx_util.printFrame("loading", 0, 0, w, h, "center", "center")
	end
end
