-- Налаштування: що саме перекладати, а що лишити мовою оригіналу.
-- Чекбокси у стандартному вікні налаштувань WoW (Esc -> Options -> AddOns).
--
-- АРХІТЕКТУРА: повна таксономія типів тексту гри закладена з самого початку.
-- Кожен тип тексту має власний ключ і чекбокс — один гравець умикає
-- українську назву свого меча, інший лишає все «механічне» англійською.
-- Модулі перекладу перед підміною тексту питають ns.IsEnabled("ключ").
--
-- Філософія типових значень:
--   СЮЖЕТНЕ (квести, діалоги, книги, субтитри)      -> українська (увімкнено)
--   МЕХАНІЧНЕ (назви предметів/заклять, стати)      -> оригінал (вимкнено),
--     бо гравці звіряють їх із гайдами, WeakAuras і рейдовими callout'ами.

local ADDON_NAME, ns = ...

-- active=false — модуль ще в розробці: чекбокс видно і зберігається,
-- запрацює щойно з'явиться відповідний модуль перекладу.
ns.optionSections = {
    {
        header = "Загальне",
        options = {
            -- Головний вимикач. Знята галочка = увесь текст мовою оригіналу (це й
            -- був сенс окремого «Вимкнути весь переклад!» — прибрано як дубль). onChange
            -- дає ЖИВИЙ ефект: перемикання одразу вертає видимий текст EN⇄UA (через
            -- ns.ShowOriginal, що тепер зважає на майстер), без /reload.
            { key = "enabled", default = true, active = true,
              label = "Увімкнути переклад",
              tooltip = "Головний вимикач. Знято — увесь текст лишається мовою оригіналу (переклад вимкнено), аддон нічого не підміняє й лише збирає тексти. Те саме одразу робить клавіша «Вимкнути весь переклад (перемикач)» у «Гра → Призначення клавіш → Аддони».",
              onChange = function()
                  if ns.ToggleOriginal then ns.ToggleOriginal() end
              end },
            { key = "originalKey", default = "SHIFT", active = true,
              control = "dropdown",
              options = { { "SHIFT", "Shift" }, { "CTRL", "Ctrl" },
                          { "ALT", "Alt" }, { "NONE", "Вимкнено" } },
              label = "Клавіша показу оригіналу (утримання)",
              tooltip = "Утримуйте цю клавішу — текст тимчасово стане англійським (зручно звірятися з гайдами). Відпустіть — знову українська.\n\nЯкщо Shift/Ctrl/Alt у вас зайняті іншими комбо й переклад блимає — оберіть «Вимкнено» та скористайтеся окремою клавішею-перемикачем у «Гра → Призначення клавіш → Аддони»." },
        },
    },
    {
        header = "Квести",
        options = {
            { key = "quests.title", default = true, active = true,
              label = "Назви квестів",
              tooltip = "Назва квесту у вікні прийняття/здачі та журналі. Вимкніть, якщо шукаєте квести за назвою в гайдах/Wowhead." },
            { key = "quests.text", default = true, active = true,
              label = "Тексти квестів",
              tooltip = "Опис, текст прогресу і завершення квесту — основний сюжетний текст." },
            { key = "quests.objectives", default = true, active = true,
              label = "Цілі квестів",
              tooltip = "Рядок цілей у вікні квесту («Вбийте 10 вовків»)." },
            { key = "quests.ui", default = true, active = true,
              label = "Заголовки вікна квесту",
              tooltip = "Службові написи вікна квесту: «Опис», «Нагороди», «Ви отримаєте:» тощо." },
            { key = "quests.tracker", default = true, active = true,
              label = "Трекер цілей на екрані",
              tooltip = "Список квестів і цілей праворуч на екрані: назви квестів українською вже зараз, рядки цілей — у міру перекладу." },
        },
    },
    {
        header = "Діалоги NPC",
        options = {
            { key = "gossip.text", default = true, active = true,
              label = "Репліки NPC",
              tooltip = "Текст, який NPC говорить у вікні розмови. Неперекладені репліки збираються і поступово додаються в базу." },
            { key = "gossip.options", default = true, active = true,
              label = "Варіанти відповідей",
              tooltip = "Пункти вибору в розмові з NPC. Неперекладені збираються і поступово додаються в базу." },
            { key = "subtitles", default = true, active = true,
              label = "Субтитри і talking heads",
              tooltip = "Репліки персонажів вголос: talking heads, бабли над головами, крики босів і монстрів у чаті." },
            { key = "books", default = true, active = false,
              label = "Книги і листи",
              tooltip = "Тексти книжок, записок і листів у світі. (Модуль у розробці.)" },
        },
    },
    {
        header = "Предмети",
        options = {
            { key = "items.name", default = false, active = true,
              label = "Назви предметів",
              tooltip = "Українська назва вашого меча у тултіпі (оригінал лишається поруч у дужках). Типово вимкнено: назви у гайдах і аукціоні англійські." },
            { key = "items.flavor", default = true, active = true,
              label = "Художні описи предметів",
              tooltip = "Жовтий «флейвор»-текст унизу тултіпа — сюжетний, на механіку не впливає." },
            { key = "items.effects", default = false, active = false,
              label = "Ефекти предметів (Use/Equip)",
              tooltip = "Рядки «Використання:» та «При спорядженні:». Типово вимкнено для звірки з гайдами. (Модуль у розробці.)" },
            { key = "items.statsSlots", default = false, active = false,
              label = "Слоти і характеристики",
              tooltip = "Назви слотів (Спина, Груди) і характеристик (Сила, Поспіх). Типово вимкнено. (Модуль у розробці.)" },
        },
    },
    {
        header = "Закляття і здібності",
        options = {
            { key = "spells.name", default = true, active = true,
              label = "Назви заклять",
              tooltip = "Українські назви заклять у книзі заклять і тултіпах. Затисни Shift, щоб тимчасово побачити оригінальні (англійські) назви — зручно для гайдів." },
            { key = "spells.description", default = false, active = true,
              label = "Описи заклять",
              tooltip = "Текст тултіпів заклять і талантів українською, з вашими живими числами (шкода, тривалість). Складні описи з умовами поки лишаються англійською." },
            { key = "auras", default = false, active = false,
              label = "Бафи і дебафи",
              tooltip = "Назви й описи ефектів на панелі бафів. (Модуль у розробці.)" },
        },
    },
    {
        header = "Світ та інше",
        options = {
            { key = "classes", default = true, active = true,
              label = "Назви класів і спеціалізацій",
              tooltip = "ПАЛАДИН, Святість, Відплата — у вікні талантів і виборі спеціалізації." },
            { key = "names.original", default = false, active = false,
              label = "Імена персонажів: оригінал (латиницею)",
              tooltip = "Показувати імена героїв англійською (Wrathion замість Вратіон), решта тексту лишається українською — зручно для звірки з гайдами. Імена виходять без відмінка («Щоденник Wrathion»). Текст не дублюється: заміна йде на льоту." },
            { key = "world.zones", default = false, active = false,
              label = "Назви зон",
              tooltip = "Назви локацій на мапі та при вході в зону. (Модуль у розробці.)" },
            { key = "world.npcNames", default = true, active = true,
              label = "Імена NPC і монстрів",
              tooltip = "Імена істот у тултіпі, на неймплейті та в рамці цілі (зокрема kill-цілі «X вбито») українською. Затисни Shift, щоб тимчасово побачити оригінальні (англійські) імена — зручно для гайдів. Імена гравців не чіпаються." },
            { key = "achievements", default = true, active = true,
              label = "Досягнення",
              tooltip = "Назви й описи досягнень у вікні досягнень українською. Типово увімкнено (сюжетно-колекційний контент). Вимкніть, якщо шукаєте досягнення за назвою в гайдах/Wowhead. Shift тимчасово показує оригінал." },
            { key = "currency", default = true, active = true,
              label = "Валюти",
              tooltip = "Назви й описи валют у тултіпах (гаманець, нагороди) і у вікні Валюти. Shift тимчасово показує оригінал." },
            { key = "mail", default = true, active = true,
              label = "Пошта",
              tooltip = "Тема й текст листів від NPC та системи (поштова скринька) українською. Особисте листування між гравцями НЕ чіпається. Текст листів серверний — перекладається той, що ви отримали в грі. Shift тимчасово показує оригінал." },
            { key = "chat", default = true, active = true,
              label = "Чат: лут, гроші, репліки NPC",
              tooltip = "Переклад у вікні чату: здобич/гроші/валюта та репліки NPC (наприклад «Valeera says…»). Вимкніть, щоб чат лишався англійським, НЕ зачіпаючи тултіпи предметів і кінематик-субтитри. Діє на нові рядки (історію чату перемалювати не можна)." },
        },
    },
    {
        header = "Збір текстів для перекладу",
        options = {
            { key = "capture.notify", default = true, active = true,
              label = "Сповіщення в чаті про зібране",
              tooltip = "Повідомлення «Новий моб …», «Зібрано квест …», «Зібрано книгу …» у чаті, коли аддон збирає неперекладений текст у грі. САМ ЗБІР працює завжди — це лише сповіщення. Вимкніть, якщо заважає." },
        },
    },
    {
        header = "Інтерфейс гри",
        options = {
            { key = "interface.menu", default = true, active = true,
              label = "Меню та налаштування",
              tooltip = "Меню Esc (Параметри, Аддони, Вийти) і пункти у вікні налаштувань гри." },
            { key = "groupfinder.names", default = true, active = true,
              label = "Назви підземель у шукачі груп (I)",
              tooltip = "Перекладати назви підземель, рейдів і глибин у вікні пошуку груп (клавіша I). Діє на списки «Зібрані групи» (підземелля Міфічний+ і глибини), вкладку «Підземелля Міфічний+» — значки сезону та їхні підказки. Вимкніть, щоб назви лишалися англійськими: зручно в міжнародних групах і для звірки з гайдами. Решта вікна (кнопки, заголовки, вкладки) однаково перекладається — нею керує опція «Меню та налаштування». Після зміни потрібен /reload." },
            { key = "interface.character", default = true, active = true,
              label = "Вікно персонажа (характеристики)",
              tooltip = "Назви характеристик (Сила, Витривалість, Критичний удар…), заголовки (Характеристики, Підсилення) і вкладки (Персонаж/Репутація/Валюта) у вікні персонажа. Вимкніть, щоб це вікно лишалося англійським — зручно для звірки з гайдами. Числа/відсотки не чіпаються." },
        },
    },
    {
        header = "Сторонні аддони (тестово)",
        options = {
            { key = "compat.kalielsTracker", default = false, active = true,
              label = "Kaliel's Tracker (тестово)",
              tooltip = "Перекладати назви квестів і цілі у трекері Kaliel's Tracker (він замінює стандартний трекер власним фреймом). ТЕСТОВА функція — після ввімкнення зробіть /reload. Якщо помітите проблеми (неправильний розмір рядків, англійські блоки, миготіння) — вимкніть і повідомте." },
        },
    },
}

ns.defaultSettings = {}
for _, section in ipairs(ns.optionSections) do
    for _, opt in ipairs(section.options) do
        ns.defaultSettings[opt.key] = opt.default
    end
end

function ns.GetSettingsDB()
    local db = _G[ADDON_NAME .. "SettingsDB"]
    if not db then
        db = {}
        _G[ADDON_NAME .. "SettingsDB"] = db
    end
    return db
end

-- Значення налаштування будь-якого типу (рядкові — для дропдаунів).
function ns.GetSetting(key)
    -- Публічна збірка: жодних сповіщень збору в чат (збирача нема).
    if ns.PUBLIC and key == "capture.notify" then return false end
    local v = ns.GetSettingsDB()[key]
    if v == nil then return ns.defaultSettings[key] end
    return v
end

-- Головна перевірка для всіх модулів перекладу.
-- Враховує головний вимикач, потім конкретний ключ.
function ns.IsEnabled(key)
    local db = ns.GetSettingsDB()
    local function value(k)
        local v = db[k]
        if v == nil then return ns.defaultSettings[k] or false end
        return v
    end
    if key ~= "enabled" and not value("enabled") then
        return false
    end
    return value(key)
end

-- true, коли треба показувати оригінал — усі модулі перекладу в цей момент
-- пропускають підміну. Незалежні шляхи: (0) МАЙСТЕР-вимикач «Увімкнути переклад»
-- знято → увесь текст оригіналом (замінив окремий «Вимкнути весь переклад!»);
-- (1) перемикач ns.originalToggled (клавіша «перемикач» у Призначенні клавіш);
-- (2) утримання ДОВІЛЬНОЇ клавіші (ns.holdOriginal — клавіша «утримання», ловиться
-- кадром-спостерігачем у Core); (3) утримання модифікатора з дропдауна.
function ns.ShowOriginal()
    if not ns.IsEnabled("enabled") then return true end
    if ns.originalToggled then return true end
    if ns.holdOriginal then return true end
    local key = ns.GetSetting("originalKey")
    if key == "SHIFT" then return IsShiftKeyDown() end
    if key == "CTRL" then return IsControlKeyDown() end
    if key == "ALT" then return IsAltKeyDown() end
    return false
end

-- Додати опції секції у вказану категорію (головну або підкатегорію).
local function AddSectionOptions(category, db, section)
    for _, opt in ipairs(section.options) do
        -- «(скоро)» — ПРЕФІКСОМ (на початку): суфікс обрізався на довгих
        -- назвах (як «Імена персонажів…»), і позначку не було видно.
        local label = opt.active and opt.label or ("(скоро) " .. opt.label)
        if opt.control == "dropdown" then
            local setting = Settings.RegisterAddOnSetting(
                category, ADDON_NAME .. "_" .. opt.key, opt.key, db,
                Settings.VarType.String, label, opt.default)
            local function GetOptions()
                local container = Settings.CreateControlTextContainer()
                for _, o in ipairs(opt.options) do
                    container:Add(o[1], o[2])
                end
                return container:GetData()
            end
            Settings.CreateDropdown(category, setting, GetOptions, opt.tooltip)
        else
            local setting = Settings.RegisterAddOnSetting(
                category,
                ADDON_NAME .. "_" .. opt.key, -- унікальний variable
                opt.key,                      -- ключ у таблиці db
                db,
                Settings.VarType.Boolean,
                label,
                opt.default
            )
            Settings.CreateCheckbox(category, setting, opt.tooltip)
            if opt.onChange then
                setting:SetValueChangedCallback(function() opt.onChange() end)
            end
        end
    end
end

local function RegisterOptionsPanel()
    -- ДЕРЕВО ЯК В AUCTIONATOR: головна сторінка = «Загальне», решта секцій —
    -- ПІДКАТЕГОРІЇ зліва (Settings.RegisterVerticalLayoutSubcategory). Ключі
    -- налаштувань ті самі — збережені значення гравців не втрачаються.
    local category, layout = Settings.RegisterVerticalLayoutCategory(ADDON_NAME)
    local db = ns.GetSettingsDB()

    -- Вступний опис угорі головної сторінки: пояснює саму суть — гравець сам
    -- обирає, що перекладати, а утримання Shift тимчасово показує оригінал
    -- (клавіша переназначувана). Секція-заголовок Settings API переносить текст.
    if not layout and SettingsPanel and SettingsPanel.GetLayout then
        layout = SettingsPanel:GetLayout(category)
    end
    if layout and CreateSettingsListSectionHeaderInitializer then
        layout:AddInitializer(CreateSettingsListSectionHeaderInitializer(
            "Оберіть, які тексти гри бачити українською, а які лишити мовою "
            .. "оригіналу. Утримуйте Shift, щоб тимчасово показати оригінал — "
            .. "клавішу можна змінити нижче або в «Гра → Призначення клавіш → Аддони»."))
    end

    for i, section in ipairs(ns.optionSections) do
        -- Публічна збірка: секція «Збір текстів для перекладу» неактуальна (збирача нема).
        if ns.PUBLIC and section.header == "Збір текстів для перекладу" then
            -- пропускаємо
        elseif i == 1 then
            AddSectionOptions(category, db, section)   -- «Загальне» на головній
        else
            local sub = Settings.RegisterVerticalLayoutSubcategory(category, section.header)
            AddSectionOptions(sub, db, section)
        end
    end

    Settings.RegisterAddOnCategory(category)
    ns.settingsCategory = category
end

function ns.OpenOptions()
    if ns.settingsCategory then
        Settings.OpenToCategory(ns.settingsCategory:GetID())
    end
end

local f = CreateFrame("Frame")
f:RegisterEvent("ADDON_LOADED")
f:SetScript("OnEvent", function(self, _, name)
    if name ~= ADDON_NAME then return end
    RegisterOptionsPanel()
    -- відновити ФІКСОВАНИЙ «показати оригінал» з минулої сесії: якщо був увімкнений,
    -- ставимо ns.originalToggled → усі хуки одразу показують оригінал (переклад «вимкнено»).
    local db = ns.GetSettingsDB and ns.GetSettingsDB()
    if db and db.showOriginal then ns.originalToggled = true end
    self:UnregisterEvent("ADDON_LOADED")
end)
