local name, ns = ...
local debug = ns.debug
local Addon = _G[name]

local L = LibStub("AceLocale-3.0"):GetLocale(name)

local AceConfig = LibStub("AceConfig-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")

local function escape(text)
	if not text then return end
	return text:replace("|","||")
end

local function unescape(text)
	if not text then return end
	return text:replace("||", "|")
end

local function codeIsValidLua(_, code)
	local _, err = loadstring(code)
	if not err then
		return true
	else
		return err
	end
end

local function showConfig()
	AceConfigDialog:SetDefaultSize(name, 950, 600)
	AceConfigDialog:Open(name)
	-- InterfaceOptionsFrame:Hide() -- hides everything...
end

function setOption(info, value)
	local key = info[#info]
	Addon.db.profile[key] = value
end
function getOption(info)
	local key = info[#info]
	return Addon.db.profile[key]
end

local lineChoices = {}
for i = 1,30 do
	lineChoices[i] = L["Line %d"]:format(i)
end

local currentLine = 1
local function setLineText(info, value)
	local side = info[#info - 1]
	local entry = Addon.db.profile[side][currentLine]
	if entry.type == "template" then
		entry.type = "code"
	end
	entry.value = unescape(value)
end

local function getLineText(info)
	local side = info[#info - 1]
	local entry = Addon.db.profile[side][currentLine]
	if entry.type == "template" then
		return escape(Addon:GetTemplateValue(entry.value))
	else
		return escape(entry.value)
	end
end

local options

local function rebuildProviderOpts(providerName, side)
	debug("rebuild provider opts ", side)
	local args = options.args.texts.args[side].args.providerOpts.args
	for k in pairs(args) do
		args[k] = nil
	end
	local providerOpts = CopyTable(Addon.providerOpts[providerName])
	if not providerOpts then
		debug("no provider opts")
		return
	end
	debug("provider opts are: ")
	debug(providerOpts)
	for k,v in pairs(providerOpts) do
		args[k] = v
		v.arg = Addon.db.profile[side][currentLine]
	end
end

local function rebuildAllProviderOpts()
	debug("rebuild both provider opts")
	local leftProvider = Addon.db.profile.left[currentLine].type
	rebuildProviderOpts(leftProvider, "left")
	local rightProvider = Addon.db.profile.right[currentLine].type
	rebuildProviderOpts(rightProvider, "right")
end

local function setType(info, value)
	local side = info[#info - 1]
	local oldType = Addon.db.profile[side][currentLine].type
	local oldValue = Addon.db.profile[side][currentLine].value
	Addon.db.profile[side][currentLine].type = value
	if oldType == "template" and value == "code" then
		Addon.db.profile[side][currentLine].value = Addon:GetTemplateValue(oldValue)
	--elseif value == "template" or oldType == "template" then
	else
		Addon.db.profile[side][currentLine].value = nil
	end
	rebuildProviderOpts(value, side)
end

local function getType(info)
	local side = info[#info - 1]
	return Addon.db.profile[side][currentLine].type
end

local function getTemplateChoices()
	return Addon:GetTemplates()
end

local function getTemplateName(info)
	local side = info[#info - 1]
	return Addon.db.profile[side][currentLine].value
end

local function setTemplateName(info, value)
	local side = info[#info - 1]
	Addon.db.profile[side][currentLine].value = value
	--[[local old = Addon.db.profile[side .. "Templates"][currentLine]
	if value == "1" then
		Addon.db.profile[side .. "Plain"][currentLine] = value
		value = nil
	else
		Addon.db.profile[side .. "Plain"][currentLine] = nil
	end
	if value == "0" then
		setLineText(info, Addon:GetTemplateValue(old))
		value = nil
	end
	Addon.db.profile[side .. "Templates"][currentLine] = value --]]
end

local function getProviderChoices()
	return Addon.providerChoices
end

local function isNotTypeTemplate(info)
	return getType(info) ~= "template"
end

local function isTypeTemplate(info)
	return getType(info) == "template"
end

local function isTypeNone(info)
	return getType(info) == "none"
end

function Addon:CreateOptions()
	if options then
		return
	end

	local leftContentArgs = {
		selectType = {
			type = 'select',
			name = L["Select Provider"],
			desc = L["Select how the text should be obtained"],
			values = getProviderChoices,
			get = getType,
			set = setType,
			order = 1,
		},
		providerOpts = {
			type = 'group',
			name = "",
			desc = "",
			args = {},
		},
	}
	local rightContentArgs = CopyTable(leftContentArgs)

	options = {
		name = L["Tooltip LuaText"],
		desc = L[""],
		type = 'group',
		set = setOption,
		get = getOption,
		args = {
			general = {
				type = 'group',
				name = L["General"],
				desc = L["General"],
				order = 1,
				args = {
					alwaysShowLefts = {
						type = 'toggle',
						name = L["Always show texts"],
						desc = L["Always show left texts, even if the right text is empty"],
						order = 1,
					},
					printErrors = {
						type = 'toggle',
						name = L["Show Errors"],
						desc = L["Print errors to Chatframe"],
						order = 3,
					},
				},
			},
			profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db),
			texts = {
				type = 'group',
				name = L["Texts"],
				desc = L["Edit Text-codes"],
				args = {
					lineselect = {
						type = 'select',
						name = L["Select line"],
						desc = L["Select the line you want to edit"],
						order = 1,
						values = lineChoices,
						get = function() return currentLine end,
						set = function(info, value) currentLine = value; rebuildAllProviderOpts() end,
					},
					left = {
						type = 'group',
						inline = true,
						name = L["Left"],
						desc = L["Edit Line Text"],
						args = leftContentArgs,
					},
					right = {
						type = 'group',
						inline = true,
						name = L["Right"],
						desc = L["Edit Line Text"],
						args = rightContentArgs,
					},
				},
				order = 2,
			}
		},
	}

	rebuildAllProviderOpts()
	AceConfig:RegisterOptionsTable(name, options)

	local options2 = {
		name = L["Tooltip LuaText"],
		desc = L[""],
		type = 'group',
		handler = self,
		args = {
			showConfig = {
				name = L["Open Configuration"],
				desc = L["Open standalone Configuration"],
				type = 'execute',
				func = "DelayedShowConfig",
			},
		},
	}

	AceConfig:RegisterOptionsTable("Tooltip_LuaText_bliz", options2)
	AceConfigDialog:AddToBlizOptions("Tooltip_LuaText_bliz", "Tooltip LuaText")

	self:RegisterChatCommand("ttl", showConfig)
	self:RegisterChatCommand("tooltiplua", showConfig)
end

function Addon:DelayedShowConfig()
	self:ScheduleTimer(showConfig, 0.1)
	InterfaceOptionsFrame:Hide()
end
