local _, addonTable = ...
local core = addonTable

core.MeetingStoneApplicantTestData = core.MeetingStoneApplicantTestData or {}
local TestData = core.MeetingStoneApplicantTestData

_G.MKA_MEETINGSTONE_APPLICANT_TEST_ROWS_ENABLED = _G.MKA_MEETINGSTONE_APPLICANT_TEST_ROWS_ENABLED == true
_G.MKA_MEETINGSTONE_APPLICANT_SCROLL_TEST_EXTRA_ROWS = tonumber(_G.MKA_MEETINGSTONE_APPLICANT_SCROLL_TEST_EXTRA_ROWS) or 24

local MEETINGSTONE_APPLICANT_ROLE_KEY_BY_LFG_ROLE = {
    TANK = "TANK",
    HEALER = "HEAL",
    HEAL = "HEAL",
    DAMAGER = "DPS",
    DPS = "DPS",
}

local MEETINGSTONE_APPLICANT_TEST_ACCOUNT_TYPES = {
    {
        name = "测试老兵",
        accountType = "veteran",
        relationship = false,
    },
    {
        name = "测试逃兵",
        accountType = "veteran",
        relationship = false,
        isLeaver = true,
        role = "DAMAGER",
        roleKey = "DPS",
        classFile = "DEMONHUNTER",
        localizedClass = "恶魔猎手",
        comment = "逃兵标识测试：类型列红色显示。",
    },
    {
        name = "测试新兵",
        accountType = "newbie",
    },
    {
        name = "测试新兵无战网",
        accountType = "newbie",
        relationship = false,
    },
    {
        name = "测试火车头",
        accountType = "leader",
        leaderLevel = 0,
    },
    {
        name = "测试星团长",
        accountType = "star",
        starLevel = 0,
        relationship = false,
    },
    {
        name = "测试新兵火车头",
        accountType = "newbie_leader",
        leaderLevel = 3,
        relationship = false,
        comment = "账号类型权重测试：新兵优先于火车头。",
    },
    {
        name = "测试火车头星团长",
        accountType = "leader_star",
        leaderLevel = 2,
        starLevel = 5,
        relationship = false,
        comment = "账号类型权重测试：火车头优先于星团长。",
    },
    {
        name = "测试三职责",
        accountType = "veteran",
        relationship = false,
        role = "TANK",
        roleKey = "TANK",
        roleKeys = { "TANK", "HEAL", "DPS" },
        classFile = "DRUID",
        localizedClass = "德鲁伊",
        comment = "三职责申请：坦克、治疗、输出。",
    },
}
local MEETINGSTONE_APPLICANT_TEST_GROUP_APPLICANT_ID = -9001
local MEETINGSTONE_APPLICANT_TEST_GROUP_KEY = "mka-test-party-3"
local MEETINGSTONE_APPLICANT_TEST_GROUP_MEMBERS = {
    {
        name = "测试三人队长",
        accountType = "veteran",
        role = "TANK",
        roleKey = "TANK",
        classFile = "WARRIOR",
        localizedClass = "战士",
        relationship = false,
        comment = "三人组队申请：队长。",
    },
    {
        name = "测试三人治疗",
        accountType = "newbie",
        role = "HEALER",
        roleKey = "HEAL",
        classFile = "PRIEST",
        localizedClass = "牧师",
        relationship = false,
        comment = "三人组队申请：治疗。",
    },
    {
        name = "测试三人输出",
        accountType = "leader",
        leaderLevel = 4,
        role = "DAMAGER",
        roleKey = "DPS",
        classFile = "MAGE",
        localizedClass = "法师",
        relationship = false,
        comment = "三人组队申请：输出。",
    },
}
local MEETINGSTONE_APPLICANT_TEST_CLASSES = {
    { classFile = "DEATHKNIGHT", localizedClass = "死亡骑士" },
    { classFile = "DEMONHUNTER", localizedClass = "恶魔猎手" },
    { classFile = "DRUID", localizedClass = "德鲁伊" },
    { classFile = "EVOKER", localizedClass = "唤魔师" },
    { classFile = "HUNTER", localizedClass = "猎人" },
    { classFile = "MAGE", localizedClass = "法师" },
    { classFile = "MONK", localizedClass = "武僧" },
    { classFile = "PALADIN", localizedClass = "圣骑士" },
    { classFile = "PRIEST", localizedClass = "牧师" },
    { classFile = "ROGUE", localizedClass = "潜行者" },
    { classFile = "SHAMAN", localizedClass = "萨满祭司" },
    { classFile = "WARLOCK", localizedClass = "术士" },
    { classFile = "WARRIOR", localizedClass = "战士" },
}
local MEETINGSTONE_APPLICANT_TEST_ROLES = {
    { role = "TANK", roleKey = "TANK" },
    { role = "HEALER", roleKey = "HEAL" },
    { role = "DAMAGER", roleKey = "DPS" },
}
local MEETINGSTONE_APPLICANT_TEST_ACCOUNT_TYPE_KEYS = {
    "veteran",
    "newbie",
    "leader",
    "star",
}
local MEETINGSTONE_APPLICANT_TEST_COMMENTS = {
    "可语音，熟路线。",
    "自备合剂和爆发药水。",
    "有门有糖，稳定不毛。",
    "来测列表 UI。",
    "熟练打断，能开麦。",
}

local function BuildMeetingStoneApplicantTestRoleFlags(primaryRoleKey, roleKeys)
    local roles = {
        TANK = false,
        HEAL = false,
        DPS = false,
    }

    local function addRole(roleKey)
        if type(roleKey) ~= "string" then
            return
        end

        local normalizedRoleKey = MEETINGSTONE_APPLICANT_ROLE_KEY_BY_LFG_ROLE[roleKey]
        if normalizedRoleKey and roles[normalizedRoleKey] ~= nil then
            roles[normalizedRoleKey] = true
        end
    end

    if type(roleKeys) == "table" then
        for _, roleKey in ipairs(roleKeys) do
            addRole(roleKey)
        end
    end

    addRole(primaryRoleKey)

    if not (roles.TANK or roles.HEAL or roles.DPS) then
        roles.DPS = true
    end

    return roles
end

local function GetMeetingStoneApplicantRandomValue(values)
    if type(values) ~= "table" or #values == 0 then
        return nil
    end

    if random then
        return values[random(1, #values)]
    end

    return values[1]
end

local function GetMeetingStoneApplicantRandomNumber(minValue, maxValue)
    if random then
        return random(minValue, maxValue)
    end

    return minValue
end

local function SeedMeetingStoneApplicantTestAccountType(applicant)
    if not (applicant and applicant.mkaMeetingStoneTestRow and core.MeetingStoneData) then
        return
    end

    core.MeetingStoneData.cache = core.MeetingStoneData.cache or {}
    local now = time and time() or 0
    local accountType = applicant.mkaMeetingStoneTestAccountType
    local cacheEntry
    if accountType == "newbie" then
        cacheEntry = {
            isNewbie = true,
            newbieExpireTime = now + (24 * 60 * 60),
            medalTime = now,
        }
    elseif accountType == "newbie_leader" then
        cacheEntry = {
            isNewbie = true,
            newbieExpireTime = now + (24 * 60 * 60),
            level = applicant.mkaMeetingStoneTestLeaderLevel or 3,
            starLevel = applicant.mkaMeetingStoneTestStarLevel,
            medalTime = now,
        }
    elseif accountType == "leader" then
        cacheEntry = {
            level = applicant.mkaMeetingStoneTestLeaderLevel or 0,
            medalTime = now,
        }
    elseif accountType == "leader_star" then
        cacheEntry = {
            level = applicant.mkaMeetingStoneTestLeaderLevel or 2,
            starLevel = applicant.mkaMeetingStoneTestStarLevel or 5,
            medalTime = now,
        }
    elseif accountType == "star" then
        cacheEntry = {
            starLevel = applicant.mkaMeetingStoneTestStarLevel or 0,
            medalTime = now,
        }
    else
        cacheEntry = {
            medalTime = now,
        }
    end

    core.MeetingStoneData.cache[applicant.name] = cacheEntry
    if type(core.MeetingStoneData.pendingNames) == "table" then
        core.MeetingStoneData.pendingNames[applicant.name] = nil
    end
end

local function CreateMeetingStoneApplicantTestRows(owner, activityID, isMythicPlusActivity)
    if _G.MKA_MEETINGSTONE_APPLICANT_TEST_ROWS_ENABLED ~= true then
        return nil
    end

    if owner and owner.mkaMeetingStoneTestApplicants then
        for _, applicant in ipairs(owner.mkaMeetingStoneTestApplicants) do
            SeedMeetingStoneApplicantTestAccountType(applicant)
        end
        return owner.mkaMeetingStoneTestApplicants
    end

    local realm = GetRealmName and GetRealmName() or "测试服"
    if type(realm) == "string" then
        realm = realm:gsub("%s+", "")
    end
    if type(realm) ~= "string" or realm == "" then
        realm = "测试服"
    end

    local applicants = {}
    for index, testInfo in ipairs(MEETINGSTONE_APPLICANT_TEST_ACCOUNT_TYPES) do
        local randomClassInfo = GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_CLASSES) or MEETINGSTONE_APPLICANT_TEST_CLASSES[1]
        local classInfo = {
            classFile = testInfo.classFile or randomClassInfo.classFile,
            localizedClass = testInfo.localizedClass or randomClassInfo.localizedClass,
        }
        local roleInfo = GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_ROLES) or MEETINGSTONE_APPLICANT_TEST_ROLES[3]
        local score = GetMeetingStoneApplicantRandomNumber(2600, 3600)
        local bestMapScore = math.max(1, score - GetMeetingStoneApplicantRandomNumber(120, 420))
        local applicant = {
            memberIndex = 1,
            numMembers = 1,
            name = string.format("%s-%s", testInfo.name, realm),
            shortName = testInfo.name,
            role = testInfo.role or roleInfo.role,
            roles = BuildMeetingStoneApplicantTestRoleFlags(testInfo.roleKey or roleInfo.roleKey, testInfo.roleKeys),
            level = 90,
            honorLevel = GetMeetingStoneApplicantRandomNumber(10, 120),
            useHonorLevel = false,
            relationship = testInfo.relationship ~= false,
            isLeaver = testInfo.isLeaver == true,
            class = classInfo.localizedClass,
            classFile = classInfo.classFile,
            score = score,
            bestScore = {
                mapScore = bestMapScore,
                bestRunLevel = GetMeetingStoneApplicantRandomNumber(8, 16),
                finishedSuccess = GetMeetingStoneApplicantRandomNumber(1, 2) == 1,
            },
            stats = {},
            activityID = activityID,
            isMythicPlusActivity = isMythicPlusActivity == true,
            itemLevel = GetMeetingStoneApplicantRandomNumber(285, 305),
            comment = testInfo.comment or GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_COMMENTS),
            applicationStatus = "applied",
            pendingApplicationStatus = nil,
            displayOrderID = index,
            statusRank = 40,
            sourceIndex = index,
            mkaMeetingStoneTestRow = true,
            mkaMeetingStoneTestAccountType = testInfo.accountType,
            mkaMeetingStoneTestLeaderLevel = testInfo.leaderLevel,
            mkaMeetingStoneTestStarLevel = testInfo.starLevel,
        }
        applicants[#applicants + 1] = applicant
    end

    local extraRowCount = math.max(0, math.floor(tonumber(_G.MKA_MEETINGSTONE_APPLICANT_SCROLL_TEST_EXTRA_ROWS) or 0))
    for extraIndex = 1, extraRowCount do
        local randomClassInfo = GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_CLASSES) or MEETINGSTONE_APPLICANT_TEST_CLASSES[1]
        local roleInfo = GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_ROLES) or MEETINGSTONE_APPLICANT_TEST_ROLES[3]
        local accountType = GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_ACCOUNT_TYPE_KEYS) or "veteran"
        local score = GetMeetingStoneApplicantRandomNumber(2600, 3600)
        local bestMapScore = math.max(1, score - GetMeetingStoneApplicantRandomNumber(120, 420))
        local displayIndex = #applicants + 1
        local shortName = string.format("滚动测试%02d", extraIndex)
        local applicant = {
            memberIndex = 1,
            numMembers = 1,
            name = string.format("%s-%s", shortName, realm),
            shortName = shortName,
            role = roleInfo.role,
            roles = BuildMeetingStoneApplicantTestRoleFlags(roleInfo.roleKey),
            level = 90,
            honorLevel = GetMeetingStoneApplicantRandomNumber(10, 120),
            useHonorLevel = false,
            relationship = GetMeetingStoneApplicantRandomNumber(1, 3) == 1,
            class = randomClassInfo.localizedClass,
            classFile = randomClassInfo.classFile,
            score = score,
            bestScore = {
                mapScore = bestMapScore,
                bestRunLevel = GetMeetingStoneApplicantRandomNumber(8, 16),
                finishedSuccess = GetMeetingStoneApplicantRandomNumber(1, 2) == 1,
            },
            stats = {},
            activityID = activityID,
            isMythicPlusActivity = isMythicPlusActivity == true,
            itemLevel = GetMeetingStoneApplicantRandomNumber(285, 305),
            comment = GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_COMMENTS),
            applicationStatus = "applied",
            pendingApplicationStatus = nil,
            displayOrderID = displayIndex,
            statusRank = 40,
            sourceIndex = displayIndex,
            mkaMeetingStoneTestRow = true,
            mkaMeetingStoneTestAccountType = accountType,
            mkaMeetingStoneTestLeaderLevel = accountType == "leader" and GetMeetingStoneApplicantRandomNumber(1, 5) or nil,
            mkaMeetingStoneTestStarLevel = accountType == "star" and GetMeetingStoneApplicantRandomNumber(1, 5) or nil,
        }
        applicants[#applicants + 1] = applicant
    end

    local groupOffset = #applicants
    for memberIndex, testInfo in ipairs(MEETINGSTONE_APPLICANT_TEST_GROUP_MEMBERS) do
        local score = GetMeetingStoneApplicantRandomNumber(2600, 3600)
        local bestMapScore = math.max(1, score - GetMeetingStoneApplicantRandomNumber(120, 420))
        local applicant = {
            applicantID = MEETINGSTONE_APPLICANT_TEST_GROUP_APPLICANT_ID,
            memberIndex = memberIndex,
            numMembers = #MEETINGSTONE_APPLICANT_TEST_GROUP_MEMBERS,
            name = string.format("%s-%s", testInfo.name, realm),
            shortName = testInfo.name,
            role = testInfo.role,
            roles = {
                TANK = testInfo.roleKey == "TANK",
                HEAL = testInfo.roleKey == "HEAL",
                DPS = testInfo.roleKey == "DPS",
            },
            level = 90,
            honorLevel = GetMeetingStoneApplicantRandomNumber(10, 120),
            useHonorLevel = false,
            relationship = testInfo.relationship == true,
            class = testInfo.localizedClass,
            classFile = testInfo.classFile,
            score = score,
            bestScore = {
                mapScore = bestMapScore,
                bestRunLevel = GetMeetingStoneApplicantRandomNumber(8, 16),
                finishedSuccess = GetMeetingStoneApplicantRandomNumber(1, 2) == 1,
            },
            stats = {},
            activityID = activityID,
            isMythicPlusActivity = isMythicPlusActivity == true,
            itemLevel = GetMeetingStoneApplicantRandomNumber(285, 305),
            comment = testInfo.comment or GetMeetingStoneApplicantRandomValue(MEETINGSTONE_APPLICANT_TEST_COMMENTS),
            applicationStatus = "applied",
            pendingApplicationStatus = nil,
            displayOrderID = groupOffset + memberIndex,
            statusRank = 40,
            sourceIndex = groupOffset + memberIndex,
            mkaMeetingStoneTestRow = true,
            mkaMeetingStoneTestGroupKey = MEETINGSTONE_APPLICANT_TEST_GROUP_KEY,
            mkaMeetingStoneTestAccountType = testInfo.accountType,
            mkaMeetingStoneTestLeaderLevel = testInfo.leaderLevel,
            mkaMeetingStoneTestStarLevel = testInfo.starLevel,
        }
        applicants[#applicants + 1] = applicant
    end

    if owner then
        owner.mkaMeetingStoneTestApplicant = nil
        owner.mkaMeetingStoneTestApplicants = applicants
    end
    for _, applicant in ipairs(applicants) do
        SeedMeetingStoneApplicantTestAccountType(applicant)
    end
    return applicants
end

TestData.SeedAccountType = SeedMeetingStoneApplicantTestAccountType
TestData.CreateRows = CreateMeetingStoneApplicantTestRows
