local _, addonTable = ...

local MKA = addonTable.MKA or addonTable.MythicKeystoneAssistant
if not MKA then
    return
end

local ACCOUNT_DEBUG_COLOR_PLAYER = "ffffd100"
local ACCOUNT_DEBUG_COLOR_RESULT = "ffffd100"
local ACCOUNT_DEBUG_COLOR_SUCCESS = "ff00ff66"
local ACCOUNT_DEBUG_COLOR_ERROR = "ffff5555"
local ACCOUNT_DEBUG_COLOR_PENDING = "ff77aaff"

local FormatAccountDebugColorText

local function TrimAccountDebugString(value)
    if type(value) ~= "string" then
        return ""
    end

    return value:match("^%s*(.-)%s*$") or ""
end

local function GetAccountDebugCharacterDisplayName()
    local name = UnitName("player") or "Unknown"
    local realm = GetRealmName() or "Unknown"

    return string.format("%s-%s", name, realm)
end

local function FormatAccountDebugAgo(timestamp)
    if type(timestamp) ~= "number" then
        return FormatAccountDebugColorText("未获取", ACCOUNT_DEBUG_COLOR_ERROR)
    end

    local now = GetTime and GetTime() or time()
    local delta = now - timestamp
    if delta < 0 then
        delta = 0
    end
    return FormatAccountDebugColorText(string.format("%.1f秒前", delta), ACCOUNT_DEBUG_COLOR_RESULT)
end

local function FormatAccountDebugBool(value)
    if value == true then
        return FormatAccountDebugColorText("是", ACCOUNT_DEBUG_COLOR_SUCCESS)
    end
    if value == false then
        return FormatAccountDebugColorText("否", ACCOUNT_DEBUG_COLOR_ERROR)
    end
    return FormatAccountDebugColorText("未知", ACCOUNT_DEBUG_COLOR_RESULT)
end

local function FormatAccountDebugMethod(value)
    if value == "netease" then
        return FormatAccountDebugColorText("网易集合石通道", ACCOUNT_DEBUG_COLOR_RESULT)
    end
    if value == "socket" then
        return FormatAccountDebugColorText("本插件网易协议通道", ACCOUNT_DEBUG_COLOR_RESULT)
    end
    if value == "acecomm" then
        return FormatAccountDebugColorText("本插件备用通道", ACCOUNT_DEBUG_COLOR_RESULT)
    end
    if value == "not_ready" then
        return FormatAccountDebugColorText("尚未连接", ACCOUNT_DEBUG_COLOR_ERROR)
    end
    return FormatAccountDebugColorText(value or "未获取", value and ACCOUNT_DEBUG_COLOR_RESULT or ACCOUNT_DEBUG_COLOR_ERROR)
end

FormatAccountDebugColorText = function(value, color)
    color = color or ACCOUNT_DEBUG_COLOR_PLAYER
    local text = tostring(value or "-")
    if text == "" or text == "-" then
        return string.format("|c%s%s|r", ACCOUNT_DEBUG_COLOR_ERROR, "未获取")
    end
    return string.format("|c%s%s|r", color, text)
end

local function FormatAccountDebugPlayerName(value)
    return FormatAccountDebugColorText(value, ACCOUNT_DEBUG_COLOR_PLAYER)
end

local function FormatAccountDebugNumber(value)
    local numberValue = tonumber(value)
    if not numberValue then
        return FormatAccountDebugColorText("未获取", ACCOUNT_DEBUG_COLOR_ERROR)
    end
    return FormatAccountDebugColorText(numberValue, ACCOUNT_DEBUG_COLOR_RESULT)
end

local function FormatAccountDebugRawValue(value)
    if value == nil or value == "" or value == "-" then
        return FormatAccountDebugColorText("未获取", ACCOUNT_DEBUG_COLOR_ERROR)
    end
    return FormatAccountDebugColorText(value, ACCOUNT_DEBUG_COLOR_RESULT)
end

local function FormatAccountDebugStatusText(value)
    value = tostring(value or "")
    if value == "" or value == "-" then
        return FormatAccountDebugColorText("未获取", ACCOUNT_DEBUG_COLOR_ERROR)
    end
    if value:find("否", 1, true)
        or value:find("拒绝", 1, true)
        or value:find("不匹配", 1, true)
        or value:find("未确认", 1, true)
        or value:find("失败", 1, true)
        or value:find("逃", 1, true)
    then
        return FormatAccountDebugColorText(value, ACCOUNT_DEBUG_COLOR_ERROR)
    end
    if value:find("是", 1, true)
        or value:find("确认", 1, true)
        or value:find("正确", 1, true)
    then
        return FormatAccountDebugColorText(value, ACCOUNT_DEBUG_COLOR_SUCCESS)
    end
    if value:find("查询", 1, true) or value:find("等待", 1, true) then
        return FormatAccountDebugColorText(value, ACCOUNT_DEBUG_COLOR_PENDING)
    end
    return FormatAccountDebugColorText(value, ACCOUNT_DEBUG_COLOR_RESULT)
end

local function FormatAccountDebugResultLine(leaderName, resultText)
    return string.format(
        "|cff33ff99[账号类型诊断] 最终查询结果：|r%s |cff33ff99=>|r %s",
        FormatAccountDebugPlayerName(leaderName),
        tostring(resultText or FormatAccountDebugStatusText(nil))
    )
end

local function FormatAccountDebugResultText(info)
    if type(info) ~= "table" then
        return FormatAccountDebugStatusText("未获取")
    end
    if info.pending == true and info.cached ~= true then
        return FormatAccountDebugStatusText("查询中")
    end
    if info.queryFailureReason == "mismatched_response" then
        return FormatAccountDebugStatusText("服务器回包不匹配，未确认")
    end
    if info.cached == true then
        return FormatAccountDebugStatusText(info.accountStatus)
    end
    return FormatAccountDebugStatusText(info.accountStatus or "未获取")
end

local function IsAccountDebugWaitingForSQGLIB(info)
    if type(info) ~= "table" or info.cached == true then
        return false
    end
    if info.lastCQGLIBSendSucceeded ~= true or type(info.lastCQGLIBSentAt) ~= "number" then
        return false
    end
    return type(info.lastSQGLIBAt) ~= "number" or info.lastSQGLIBAt < info.lastCQGLIBSentAt
end

function MKA:DebugAccountTypeLookup(rawName, retryCount, readOnly)
    local meetingStoneData = addonTable.MeetingStoneData
    if not (meetingStoneData and meetingStoneData.DebugQueryLeader) then
        self:Print(FormatAccountDebugColorText("[账号类型诊断] MeetingStoneData 不可用。", ACCOUNT_DEBUG_COLOR_ERROR))
        return
    end

    local queryName = TrimAccountDebugString(rawName or "")
    if queryName == "" then
        queryName = GetAccountDebugCharacterDisplayName()
    end

    local info
    if readOnly and meetingStoneData.GetDebugInfo then
        info = meetingStoneData:GetDebugInfo(queryName)
    else
        info = meetingStoneData:DebugQueryLeader(queryName)
    end
    info = type(info) == "table" and info or {}

    local queryLeaderName = info.leader or queryName
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 查询对象：|r%s",
        FormatAccountDebugPlayerName(queryLeaderName)
    ))
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 连接状态：|r插件通道可用=%s 已连上=%s 可发送=%s 正在连接=%s 目标=%s",
        FormatAccountDebugBool(info.socketAvailable),
        FormatAccountDebugBool(info.socketReady),
        FormatAccountDebugBool(info.ready),
        FormatAccountDebugBool(info.connecting),
        FormatAccountDebugPlayerName(info.target)
    ))
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 查询发送：|r已发送=%s 方式=%s 时间=%s 名单=%s",
        FormatAccountDebugBool(info.lastCQGLIBSendSucceeded),
        FormatAccountDebugMethod(info.lastCQGLIBSendMethod),
        FormatAccountDebugAgo(info.lastCQGLIBSentAt),
        FormatAccountDebugPlayerName(info.lastCQGLIBNames)
    ))
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 登录包：|r已发送=%s 方式=%s 目标=%s 缓存摘要=%s 项 键=%s",
        FormatAccountDebugBool(info.lastSLOGINSendSucceeded),
        FormatAccountDebugMethod(info.lastSLOGINSendMethod),
        FormatAccountDebugPlayerName(info.lastSLOGINSendTarget),
        FormatAccountDebugNumber(info.lastSLOGINQueryDataCount or 0),
        FormatAccountDebugRawValue(info.lastSLOGINQueryDataKeys)
    ))
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 最近服务端消息：|r时间=%s 类型=%s 来自=%s",
        FormatAccountDebugAgo(info.lastServerMessageAt),
        FormatAccountDebugRawValue(info.lastServerMessageCmd),
        FormatAccountDebugPlayerName(info.lastServerMessageSender)
    ))
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 登录状态：|r登录时间=%s 版本=%s 来源=%s 来源兜底=%s 查询资料=%s 服务端确认=%s 服务端版本=%s 支持=%s 交易状态时间=%s 交易=%s",
        FormatAccountDebugAgo(info.lastSLOGINAt),
        FormatAccountDebugRawValue(info.lastSLOGINVersion),
        FormatAccountDebugRawValue(info.lastSLOGINSource),
        FormatAccountDebugBool(info.lastSLOGINSourceFallback),
        FormatAccountDebugRawValue(info.lastSLOGINQueryDataType),
        FormatAccountDebugAgo(info.lastSVERSIONAt),
        FormatAccountDebugRawValue(info.lastSVERSIONVersion),
        FormatAccountDebugBool(info.lastSVERSIONSupported),
        FormatAccountDebugAgo(info.lastSQTBAt),
        FormatAccountDebugBool(info.lastSQTBIsDeal)
    ))
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 服务器返回：|r返回时间=%s 数量=%s 已更新=%s 玩家=%s 匹配当前查询=%s 不匹配=%s 无效返回时间=%s 无效类型=%s",
        FormatAccountDebugAgo(info.lastSQGLIBAt),
        FormatAccountDebugNumber(info.lastSQGLIBCount),
        FormatAccountDebugBool(info.lastSQGLIBChanged),
        FormatAccountDebugPlayerName(info.lastSQGLIBLeaderNames),
        FormatAccountDebugBool(info.lastSQGLIBMatchesQuery),
        FormatAccountDebugPlayerName(info.lastSQGLIBMismatchedNames),
        FormatAccountDebugAgo(info.lastSQGLIBInvalidAt),
        FormatAccountDebugRawValue(info.lastSQGLIBInvalidType)
    ))
    self:Print(string.format(
        "|cff33ff99[账号类型诊断] 当前结果：|r已有缓存=%s 缓存新鲜=%s 缓存所属=%s 显示=%s 查询状态=%s 原因=%s 火车头=%s 星团长=%s 来源=%s 来源兜底=%s 新兵=%s 查询中=%s 待发送=%s 网易待查=%s",
        FormatAccountDebugBool(info.cached),
        FormatAccountDebugBool(info.cacheFresh),
        FormatAccountDebugPlayerName(info.cachedLeaderName),
        FormatAccountDebugStatusText(info.accountStatus),
        FormatAccountDebugRawValue(info.queryStatus),
        FormatAccountDebugRawValue(info.queryFailureReason),
        FormatAccountDebugNumber(info.level),
        FormatAccountDebugNumber(info.starLevel),
        FormatAccountDebugRawValue(info.cacheSource),
        FormatAccountDebugBool(info.cacheSourceFallback),
        FormatAccountDebugBool(info.isNewbie),
        FormatAccountDebugBool(info.pending),
        FormatAccountDebugNumber(info.pendingCount or 0),
        FormatAccountDebugNumber(info.nativePendingCount or 0)
    ))

    retryCount = type(retryCount) == "number" and retryCount or 0
    local waitingForSQGLIB = IsAccountDebugWaitingForSQGLIB(info)
    local shouldRetry = retryCount < 4
        and (info.connecting or waitingForSQGLIB or (info.pending and not info.lastSQGLIBAt))

    if shouldRetry and C_Timer and C_Timer.After then
        local delay = info.connecting and 4 or 8
        local reason = "查询已排队，等待登录稳定后发送"
        if info.connecting then
            reason = "连接/回包尚未完成"
        elseif waitingForSQGLIB then
            reason = "查询已发送，正在等待服务器返回"
        end
        self:Print(string.format(
            "|cff33ff99[账号类型诊断] %s，%s 秒后自动复查。|r",
            reason,
            FormatAccountDebugNumber(delay)
        ))
        C_Timer.After(delay, function()
            if self.DebugAccountTypeLookup then
                self:DebugAccountTypeLookup(queryName, retryCount + 1, true)
            end
        end)
    else
        self:Print("|cff33ff99[账号类型诊断] 3-10 秒后再执行同一命令；若服务器返回时间/数量更新，说明服务器已回包。|r")
    end

    self:Print(FormatAccountDebugResultLine(queryLeaderName, FormatAccountDebugResultText(info)))
end

function MKA:RefreshAccountTypeCache()
    local meetingStoneData = addonTable.MeetingStoneData
    if not (meetingStoneData and meetingStoneData.ClearAccountTypeCache) then
        self:Print(FormatAccountDebugColorText("[账号类型刷新] MeetingStoneData 不可用。", ACCOUNT_DEBUG_COLOR_ERROR))
        return
    end

    local clearedCount = meetingStoneData:ClearAccountTypeCache()
    self:Print(string.format(
        "|cff33ff99[账号类型刷新] 已清空账号类型缓存：|r%s |cff33ff99条。|r",
        FormatAccountDebugNumber(clearedCount or 0)
    ))

    if C_LFGList and C_LFGList.RefreshApplicants then
        pcall(C_LFGList.RefreshApplicants)
    end

    if self.RefreshMainWindow then
        self:RefreshMainWindow("MeetingStoneData", "AccountRefresh")
    end

    self:Print("|cff33ff99[账号类型刷新] 当前队伍/集合石/寻找队伍列表会重新查询，通常 3-10 秒内回包。|r")
end
