local addonName, BM = ...

BM = BM or {}
BM.frame = CreateFrame("Frame")
BM.currentTab = "inbox"
BetterMailboxDB = BetterMailboxDB or {}

local function DetectDefaultLanguage()
    local locale = GetLocale and GetLocale() or "enUS"
    if locale == "deDE" then return "de" end
    if locale == "frFR" then return "fr" end
    if locale == "ruRU" then return "ru" end
    return "en"
end

BetterMailboxDB.language = BetterMailboxDB.language or DetectDefaultLanguage()
BetterMailboxDB.scale = BetterMailboxDB.scale or 1
BetterMailboxDB.fontSize = BetterMailboxDB.fontSize or 12
BetterMailboxDB.fontFace = BetterMailboxDB.fontFace or 'FRIZQT__'
BetterMailboxDB.recipientHistory = BetterMailboxDB.recipientHistory or {}

local f = BM.frame

f:RegisterEvent("ADDON_LOADED")
f:RegisterEvent("MAIL_SHOW")
f:RegisterEvent("MAIL_CLOSED")
f:RegisterEvent("MAIL_INBOX_UPDATE")
f:RegisterEvent("MAIL_SEND_SUCCESS")
f:RegisterEvent("MAIL_FAILED")
f:RegisterEvent("MAIL_SEND_INFO_UPDATE")

local hideHooked
local hiddenParent
local hideTicker
local sendMailFrameHooked

local hiddenControls = {
    "SendMailFrame",
    "InboxFrame",
    "OpenMailFrame",
    "SendMailNameEditBox",
    "SendMailSubjectEditBox",
    "SendMailBodyEditBox",
    "SendMailScrollFrame",
    "SendMailPackageButton",
    "SendMailCostMoneyFrame",
    "SendMailMoney",
    "SendMailCODButton",
    "SendMailMailButton",
    "SendMailCancelButton",
}

local function GetHiddenParent()
    if hiddenParent then
        return hiddenParent
    end

    hiddenParent = CreateFrame("Frame", nil, UIParent)
    hiddenParent:Hide()
    return hiddenParent
end

local function EnsureMailUI()
    local isLoaded = false

    if C_AddOns and C_AddOns.IsAddOnLoaded then
        isLoaded = C_AddOns.IsAddOnLoaded("Blizzard_MailUI")
    elseif IsAddOnLoaded then
        isLoaded = IsAddOnLoaded("Blizzard_MailUI")
    end

    if not isLoaded then
        if C_AddOns and C_AddOns.LoadAddOn then
            pcall(C_AddOns.LoadAddOn, "Blizzard_MailUI")
        elseif LoadAddOn then
            pcall(LoadAddOn, "Blizzard_MailUI")
        end
    end
end

local function HideDefaultMailFrame()
    if not MailFrame then return end

    local parent = GetHiddenParent()

    MailFrame:SetParent(parent)
    MailFrame:SetAlpha(0)
    MailFrame:EnableMouse(false)
    MailFrame:ClearAllPoints()
    MailFrame:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", -2000, 2000)

    for _, name in ipairs(hiddenControls) do
        local frame = _G[name]
        if frame then
            frame:SetParent(parent)
            frame:SetAlpha(0)
            frame:EnableMouse(false)
            frame:Hide()

            if not frame.BetterMailboxHideHooked then
                frame:HookScript("OnShow", function(self)
                    self:SetParent(GetHiddenParent())
                    self:SetAlpha(0)
                    self:EnableMouse(false)
                    self:Hide()
                    GameTooltip_Hide()
                end)
                frame.BetterMailboxHideHooked = true
            end
        end
    end

end

local function OpenBagsForSendMail()
    if BM.OpenInventoryBags then
        BM:OpenInventoryBags()
    end
end

local function HookSendMailFrame()
    if sendMailFrameHooked or not SendMailFrame then
        return
    end

    SendMailFrame:HookScript("OnShow", function()
        OpenBagsForSendMail()
        if C_Timer then
            C_Timer.After(0.15, OpenBagsForSendMail)
        end
    end)
    sendMailFrameHooked = true
end

local function RestoreDefaultMailFrame()
    if not MailFrame then return end

    MailFrame:SetParent(UIParent)
    MailFrame:SetAlpha(1)
    MailFrame:EnableMouse(true)
    MailFrame:ClearAllPoints()
    MailFrame:SetPoint("CENTER")

    for _, name in ipairs(hiddenControls) do
        local frame = _G[name]
        if frame then
            frame:SetParent(MailFrame)
            frame:SetAlpha(1)
            frame:EnableMouse(true)
            frame:Show()
        end
    end

end

local function DisableDefaultMail()
    if not MailFrame then return end

    HideDefaultMailFrame()

    if hideTicker then
        hideTicker:Cancel()
    end
    hideTicker = C_Timer.NewTicker(0.2, HideDefaultMailFrame)

    if not hideHooked then
        hooksecurefunc("ShowUIPanel", function(panel)
            if panel == MailFrame then
                C_Timer.After(0, HideDefaultMailFrame)
            end
        end)
        hideHooked = true
    end
end

f:SetScript("OnEvent", function(_, event, arg1)
    if event == "ADDON_LOADED" and arg1 == addonName then
        BetterMailboxDB = BetterMailboxDB or {}
        BetterMailboxDB.language = BetterMailboxDB.language or DetectDefaultLanguage()
        BetterMailboxDB.scale = BetterMailboxDB.scale or 1
        BetterMailboxDB.fontSize = BetterMailboxDB.fontSize or 12
BetterMailboxDB.fontFace = BetterMailboxDB.fontFace or 'FRIZQT__'
    end

    if event == "ADDON_LOADED" and arg1 == "Blizzard_MailUI" then
        HookSendMailFrame()
        DisableDefaultMail()
    end

    if event == "MAIL_SHOW" then
        EnsureMailUI()
        HookSendMailFrame()
        DisableDefaultMail()
        CheckInbox()
        if BM.ShowUI then BM:ShowUI() end
        C_Timer.After(0.25, function()
            if BM.RefreshInbox then BM:RefreshInbox() end
        end)

    elseif event == "MAIL_CLOSED" then
        if hideTicker then
            hideTicker:Cancel()
            hideTicker = nil
        end
        if BM.CloseInventoryBagsOpenedForSend then
            BM:CloseInventoryBagsOpenedForSend()
        end
        RestoreDefaultMailFrame()
        BM.uiReady = false
        if BM.HideUI then BM:HideUI() end

    elseif event == "MAIL_INBOX_UPDATE" then
        if BM.uiReady and BM.RefreshInbox then BM:RefreshInbox() end

    elseif event == "MAIL_SEND_SUCCESS" then
        if BM.HandleSendSuccess then BM:HandleSendSuccess() end

    elseif event == "MAIL_FAILED" then
        if BM.HandleSendFailure then BM:HandleSendFailure() end

    elseif event == "MAIL_SEND_INFO_UPDATE" then
        if BM.RefreshAttachmentSlots then BM:RefreshAttachmentSlots() end
    end
end)

