local _, addon = ...

local WowQuestTextMethod = {
    Description = GetQuestText,
    Objective = GetObjectiveText,
};

local function GetWowQuestText(method)
    local text = WowQuestTextMethod[method]();
    if text then
        return text
    else
        return ""
    end
end

local function GetQuestLogQuestIndex(questID)
    local numEntries = C_QuestLog.GetNumQuestLogEntries()
    for questLogIndex = 1, numEntries do
        local info = C_QuestLog.GetInfo(questLogIndex)
        if info and info.questID == questID then
            return questLogIndex
        end
    end
    return nil
end

local function ReplaceWithBothPlaceholderMarks(t, key, value)
    if value == nil then return t end
    t = string.gsub(t, '<' .. key .. '>', value)
    t = string.gsub(t, '{' .. key .. '}', value)
    return t
end

local function FillPlaceholders(text)
    if text == nil then
        return text
    end

    local playerName = UnitName("player")
    local _, playerClass = UnitClass("player")
    local _, playerRace = UnitRace("player")

    local class = CzechQuestsAddon:GetData("class", playerClass);
    local race = CzechQuestsAddon:GetData("race", playerRace);

    local formatted = text;

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'name', playerName);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cF0', class.f0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cF1', class.f1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cF2', class.f2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cF3', class.f3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cF4', class.f4);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cF5', class.f5);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cM0', class.m0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cM1', class.m1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cM2', class.m2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cM3', class.m3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cM4', class.m4);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cL0', class.cl0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cL1', class.cl1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cL2', class.cl2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cL3', class.cl3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cL4', class.cl4);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cE0', class.ce0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cE1', class.ce1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cE2', class.ce2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cE3', class.ce3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'cE4', class.ce4);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rF0', race.f0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rF1', race.f1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rF2', race.f2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rF3', race.f3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rF4', race.f4);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rF5', race.f5);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rM0', race.m0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rM1', race.m1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rM2', race.m2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rM3', race.m3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rM4', race.m4);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rL0', race.rl0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rL1', race.rl1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rL2', race.rl2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rL3', race.rl3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rL4', race.rl4);

    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rE0', race.re0);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rE1', race.re1);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rE2', race.re2);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rE3', race.re3);
    formatted = ReplaceWithBothPlaceholderMarks(formatted, 'rE4', race.re4);

    formatted = addon.API.GetCzechOriginalText(formatted)

    return formatted
end

local function GetQuestText(questTranslation, original)
    if questTranslation == nil then
        return nil
    end
    local translation = questTranslation.text
    local paragraphs = addon.API.ParseParagraphs(original, translation)
    return FillPlaceholders(paragraphs)
end

local function GetQuestForGender(id, key, gender)
    local base = id .. "_" .. key .. "_"
    return addon.data.quest[base .. gender] or addon.data.quest[base .. "M"]
end

local function GetQuest(id, gender)
    local questName = GetQuestForGender(id, "QUEST_NAME", gender)
    local questObjective = GetQuestForGender(id, "QUEST_OBJECTIVE", gender)
    local questDescription = GetQuestForGender(id, "QUEST_DESCRIPTION", gender)
    local questProgress = GetQuestForGender(id, "QUEST_PROGRESS", gender)
    local questCompletion = GetQuestForGender(id, "QUEST_COMPLETION", gender)

    if questName or questObjective or questDescription or questProgress or questCompletion then
        local description = ""
        local objective = ""

        if QuestMapDetailsScrollFrame and QuestMapDetailsScrollFrame:IsVisible() then
            local index = GetQuestLogQuestIndex(id)
            description, objective = GetQuestLogQuestText(index)
        else
            description = GetWowQuestText("Description")
            objective = GetWowQuestText("Objective")
        end

        return {
            title = GetQuestText(questName),
            objective = GetQuestText(questObjective, objective),
            description = GetQuestText(questDescription, description),
            progress = GetQuestText(questProgress),
            completion = GetQuestText(questCompletion),
        }
    end
end
addon.API.GetQuest = GetQuest

local function GetBook(name, gender)
    local book = addon.data.book[name]
    local pages = {}

    if book == nil then
        return nil
    end

    for key, value in pairs(book) do
        if key ~= 'name' then
            local pageNum = key:match("[MF]_(%d+)")
            if pageNum then
                local pageText = book[gender .. "_" .. pageNum] or book["M_" .. pageNum]
                pages[tonumber(pageNum)] = FillPlaceholders(pageText)
            end
        end
    end

    return {
        name = book.name,
        pages = pages,
    }
end
addon.API.GetBook = GetBook