local _, addon = ...
local L = addon.L;
local API = addon.API;
local StaticPopupUtil = addon.StaticPopupUtil;

local GetContainerNumSlots = C_Container.GetContainerNumSlots;
local GetItemNameByID = C_Item.GetItemNameByID;
local GetLogIndexForQuestID = C_QuestLog.GetLogIndexForQuestID;
local IsWarbandCompleted = C_QuestLog.IsQuestFlaggedCompletedOnAccount;
local GetHyperlink = addon.TooltipAPI.GetHyperlink;
local GetNumQuestLeaderBoards = GetNumQuestLeaderBoards;
local GetQuestLogLeaderBoard = GetQuestLogLeaderBoard;
local CursorHasItem = CursorHasItem;

local POPUP_WHICH = "DELETE_QUEST_ITEM";
local EL = CreateFrame("Frame");

EL.ItemNameToQuest = {};

function EL:OnEvent(event, ...)
    self[event](self, ...)
end

function EL:DELETE_ITEM_CONFIRM(itemName, qualityID, bonding, questWarn)
    if questWarn == 1 then
        self.pendingItemName = itemName;
        local questID = self:GetQuesIDtByItemName(itemName);
        if questID then
            self:DisplayQuest(questID);
        else
            self:UpdateBagData();
        end
    end
end

function EL:BANKFRAME_OPENED()
    self.isAtBank = true;
end

function EL:BANKFRAME_CLOSED()
    self.isAtBank = false;
end

function EL:QUEST_DATA_LOAD_RESULT(questID, success)
    if questID == self.questID and success then
        self:DisplayQuest(questID);
    end
end

function EL:CURSOR_CHANGED()
    if not CursorHasItem() then
        self:HideUI();
    end
end

function EL:HideUI()
    self:UnregisterEvent("TOOLTIP_DATA_UPDATE");
    self:UnregisterEvent("CURSOR_CHANGED");
    self.questID = nil;
    StaticPopupUtil:HidePopupWidget(POPUP_WHICH);
end

function EL:EnableModule(state)
    if state then
        self.enabled = true;
        self:RegisterEvent("DELETE_ITEM_CONFIRM");
        self:RegisterEvent("BANKFRAME_OPENED");
        self:RegisterEvent("BANKFRAME_CLOSED");
        self:SetScript("OnEvent", self.OnEvent);
    elseif self.enabled then
        self.enabled = nil;
        self:UnregisterEvent("DELETE_ITEM_CONFIRM");
        self:UnregisterEvent("BANKFRAME_OPENED");
        self:UnregisterEvent("BANKFRAME_CLOSED");
        self:SetScript("OnEvent", nil);
        self:HideUI();
    end
end

local CHARACTER_BAGS = {
    0, 1, 2, 3, 4,
};

local BANK_BAGS = {
    -1, 6, 7, 8, 9, 10, 11, 12,
};

function EL:UpdateBags(bags)
    local GetContainerItemQuestInfo = C_Container.GetContainerItemQuestInfo;
    local GetContainerItemID = C_Container.GetContainerItemID;
    local GetItemInfoInstant = C_Item.GetItemInfoInstant;

    --Conundrum:
    --GetContainerItemQuestInfo returns table - increase RAM usage
    --Alternatively we use GetItemInfoInstant(itemID) to find QuestItem

    local _, itemID, classID, subclassID, info;

    for _, bagIndex in ipairs(bags) do
        for slot = 1, GetContainerNumSlots(bagIndex) do
            itemID = GetContainerItemID(bagIndex, slot);
            if itemID then
                _, _, _, _, _, classID, subclassID = GetItemInfoInstant(itemID);
                if classID == 12 then
                    info = GetContainerItemQuestInfo(bagIndex, slot);
                    if info and info.questID then
                        self:StoreItemQuest(itemID, info.questID);
                    end
                end
            end
        end
    end
end

function EL:UpdateBagData()
    self:UpdateBags(CHARACTER_BAGS);
    if self.isAtBank then
        self:UpdateBags(BANK_BAGS);
    end

    local questID = self:GetQuesIDtByItemName(self.pendingItemName);
    if questID then
        self:DisplayQuest(questID);
    end
end

function EL:OnUpdate_UnregisterDynamicEvents(elapsed)
    self.t = self.t + elapsed;
    if self.t > 1.0 then
        self.t = nil;
        self:SetScript("OnUpdate", nil);
        self:UnregisterEvent("QUEST_DATA_LOAD_RESULT");
    end
end

function EL:ListenDynamicEvents()
    self:RegisterEvent("CURSOR_CHANGED");
    self:RegisterEvent("QUEST_DATA_LOAD_RESULT");
    self.t = 0;
    self:SetScript("OnUpdate", self.OnUpdate_UnregisterDynamicEvents);
end

function EL:DisplayQuest(questID)
    self.questID = questID;

    local questName;
    local questLogIndex = GetLogIndexForQuestID(questID);
    local tooltipData = GetHyperlink("quest:"..questID);
    self:ListenDynamicEvents();

    local tooltipText;
    local dataInstanceID;

    if tooltipData and tooltipData.lines then
        dataInstanceID = tooltipData.dataInstanceID;
        local colorizedText;
        for i, line in ipairs(tooltipData.lines) do
            if i == 1 then
                questName = line.leftText;
            else
                if line.leftText then
                    if line.leftText ~= " " or tooltipText ~= nil then
                        if line.leftColor then
                            colorizedText = line.leftColor:WrapTextInColorCode(line.leftText);
                        else
                            colorizedText = line.leftText;
                        end

                        if tooltipText then
                            tooltipText = tooltipText.."\n"..colorizedText
                        else
                            tooltipText = colorizedText;
                        end
                    end
                end
            end
        end
    end

    if tooltipText and IsWarbandCompleted(questID) then
        --QUEST_REWARD_CONTEXT_FONT_COLOR   --350000
        tooltipText = tooltipText .. "\n\n".."|cff88aaff"..ACCOUNT_COMPLETED_QUEST_NOTICE.."|r";
    end

    if not questName then
        C_QuestLog.RequestLoadQuestByID(questID);
    end

    --[[
    if questLogIndex then
        --On quest
        local numObjectives = GetNumQuestLeaderBoards(questLogIndex);
        if numObjectives > 0 then
            local str;
            local text, objectiveType, finished;
            local n = 0;
            for i = 1, numObjectives do
                text, objectiveType, finished = GetQuestLogLeaderBoard(i, questLogIndex);
                if text then
                    if str then
                        str = str.."\n".."- "..text;
                    else
                        str = "- "..text;
                    end
                end
            end
            --print(str);
        end
    else
        --Not on quest

    end
    --]]

    if StaticPopupUtil:ShowSimpleTooltip(POPUP_WHICH, questName, tooltipText, "BOTTOM") then
        StaticPopupUtil:AddTooltipInfoCallback(dataInstanceID, function()
            EL:DisplayQuest(questID);
        end);
    end
end

function EL:StoreItemQuest(itemID, questID)
    local itemName = GetItemNameByID(itemID);
    if itemName and itemName ~= "" and questID ~= 0 then
        self.ItemNameToQuest[itemName] = questID;
        return true
    end
end

function EL:GetQuesIDtByItemName(itemName)
    if itemName then
        return self.ItemNameToQuest[itemName]
    end
end

do
    local function EnableModule(state)
        if state then
            EL:EnableModule(true);
        else
            EL:EnableModule(false);
        end
    end


    local moduleData = {
        name = L["ModuleName QuestItemDestroyAlert"],
        dbKey = "QuestItemDestroyAlert",
        description = L["ModuleDescription QuestItemDestroyAlert"],
        toggleFunc = EnableModule,
        categoryID = 1,
        uiOrder = 1145,
        moduleAddedTime = 1729500000,
        categoryKeys = {"Quest, Inventory"},
    };

    addon.ControlCenter:AddModule(moduleData);
end