--[[ In-journal preferences. The locale selector is deliberately explicit: it
     changes only Shiny Hunter and never promises to change the game client. ]]

local _, ns = ...

local OptionsPanel = ns.NewModule("OptionsPanel")
ns.UI = ns.UI or {}
ns.UI.OptionsPanel = OptionsPanel

local Theme = ns.UI.Theme
local LOCALES = { "auto", "enUS", "enGB", "esES", "deDE", "frFR", "itIT", "ptBR" }

-- The same list "/shiny help" prints. Kept as keys rather than as literal text
-- so a player reading this panel and a player typing the command can never be
-- told two different things.
local COMMAND_KEYS = {
    "CMD_HELP_OPEN",
    "CMD_HELP_SIGHTINGS",
    "CMD_HELP_SHARE",
    "CMD_HELP_STABLE",
    "CMD_HELP_PORTAL",
    "CMD_HELP_VERSION",
    "CMD_HELP_DEBUG",
    "CMD_HELP_DUMP",
    "CMD_HELP_VALIDATE",
    "CMD_HELP_RESET",
    "CMD_HELP_HELP",
}

-- The language column is exactly as wide as the buttons beneath it, and the
-- commands column starts after a clear gutter.
local LANGUAGE_COLUMN_WIDTH = 360

-- Below the taller hint paragraph and the "Active:" line under it.
local LANGUAGE_ROWS_TOP = -186
local COMMAND_COLUMN_X = 412
local COMMAND_ROW_SPACING = 34
local COMMAND_LINE_HEIGHT = 15

--- Splits "/shiny debug - toggle diagnostics" into its two halves.
-- Every locale pack follows that shape, but a translation that does not is a
-- reason to show the whole line unstyled, never a reason to show nothing.
-- @return string command, string|nil description
local function SplitCommand(text)
    local command, description = text:match("^(.-)%s+%-%s+(.+)$")
    if command and command ~= "" then
        return command, description
    end
    return text, nil
end

local function LocaleName(locale)
    if locale == "auto" then
        return ns.L["OPTIONS_LANGUAGE_AUTO"]:format(ns.Localization:GetClientLocale())
    end
    return ns.L["LOCALE_" .. locale:upper()] or locale
end

function OptionsPanel:Create(parent)
    local panel = { rows = {} }
    local title = parent:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT", parent, "TOPLEFT", 24, -20)
    title:SetTextColor(Theme.color.gold[1], Theme.color.gold[2], Theme.color.gold[3])
    local section = parent:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    section:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -32)
    section:SetTextColor(Theme.color.tracker[1], Theme.color.tracker[2], Theme.color.tracker[3])
    local hint = parent:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    hint:SetPoint("TOPLEFT", section, "BOTTOMLEFT", 0, -8)
    -- Width, not a right anchor to the panel edge: the commands column lives
    -- over there now, and a paragraph stretched the full width wrapped its
    -- lines straight through it.
    hint:SetWidth(LANGUAGE_COLUMN_WIDTH)
    hint:SetJustifyH("LEFT")
    hint:SetJustifyV("TOP")
    hint:SetWordWrap(true)
    hint:SetTextColor(Theme.color.muted[1], Theme.color.muted[2], Theme.color.muted[3])
    -- Four lines at this width in the wordiest locale. The paragraph used to
    -- span the whole panel and fit in two.
    hint:SetHeight(56)
    local active = parent:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    active:SetPoint("TOPLEFT", hint, "BOTTOMLEFT", 0, -12)
    active:SetTextColor(Theme.color.text[1], Theme.color.text[2], Theme.color.text[3])

    for index, locale in ipairs(LOCALES) do
        local row = CreateFrame("Button", nil, parent, "BackdropTemplate")
        row:SetPoint("TOPLEFT", parent, "TOPLEFT", 24,
            LANGUAGE_ROWS_TOP - (index - 1) * 39)
        row:SetSize(LANGUAGE_COLUMN_WIDTH, 32)
        row:SetNormalFontObject(GameFontNormal)
        row.locale = locale
        row:SetScript("OnClick", function(self)
            ns.Config:Set("language", self.locale)
        end)
        panel.rows[index] = row
    end

    -- Slash commands are the part of the addon nobody discovers. They are
    -- listed beside the language rows rather than behind another tab: an
    -- option you have to go looking for is an option that does not exist.
    local commandsTitle = parent:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    commandsTitle:SetPoint("TOPLEFT", parent, "TOPLEFT", COMMAND_COLUMN_X, -52)
    commandsTitle:SetTextColor(Theme.color.tracker[1], Theme.color.tracker[2],
        Theme.color.tracker[3])

    panel.commandRows = {}
    for index, key in ipairs(COMMAND_KEYS) do
        local top = -84 - (index - 1) * COMMAND_ROW_SPACING

        local command = parent:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
        command:SetPoint("TOPLEFT", parent, "TOPLEFT", COMMAND_COLUMN_X, top)
        command:SetPoint("RIGHT", parent, "RIGHT", -28, 0)
        command:SetJustifyH("LEFT")
        command:SetWordWrap(false)
        command:SetTextColor(Theme.color.gold[1], Theme.color.gold[2],
            Theme.color.gold[3])

        local description = parent:CreateFontString(nil, "ARTWORK",
            "GameFontHighlightSmall")
        description:SetPoint("TOPLEFT", command, "BOTTOMLEFT", 0, -1)
        description:SetPoint("RIGHT", parent, "RIGHT", -28, 0)
        description:SetJustifyH("LEFT")
        description:SetWordWrap(false)
        description:SetHeight(COMMAND_LINE_HEIGHT)
        description:SetTextColor(Theme.color.muted[1], Theme.color.muted[2],
            Theme.color.muted[3])

        panel.commandRows[index] = {
            key = key, Command = command, Description = description,
        }
    end

    function panel:Refresh()
        local L = ns.L
        commandsTitle:SetText(L["CMD_HELP_HEADER"])

        -- Rebuilt on every refresh because changing language has to retranslate
        -- this list too.
        for _, row in ipairs(self.commandRows) do
            local command, description = SplitCommand(L[row.key])
            row.Command:SetText(command)
            row.Description:SetText(description or "")
            row.Description:SetShown(description ~= nil)
        end

        title:SetText(L["OPTIONS_TITLE"])
        section:SetText(L["OPTIONS_LANGUAGE_TITLE"])
        hint:SetText(L["OPTIONS_LANGUAGE_HINT"])
        active:SetText(L["OPTIONS_LANGUAGE_ACTIVE"]:format(
            LocaleName(ns.Localization:GetEffectiveLocale())))
        local selected = ns.Config:Get("language") or "auto"
        for _, row in ipairs(self.rows) do
            row:SetText(LocaleName(row.locale))
            Theme:ApplyButton(row, row.locale == selected)
        end
    end
    panel:Refresh()
    return panel
end
