-- 用于限制最大候选数量以及重复最大输入编码,防止卡顿性能异常
--@amzxyz
--https://github.com/amzxyz
local M            = {}
local ACCEPT, PASS = 1, 2

local MAX_REPEAT   = 8  -- 连续重复输入声母上限
local MAX_SEGMENTS = 40 -- 允许的最大“分段”数
local INITIALS     = "[bpmfdtnlgkhjqxrzcsywiu]"

-- 计算末尾重复
local function tail_rep(s)
    local last, n = s:sub(-1), 1
    for i = #s - 1, 1, -1 do
        if s:sub(i, i) == last then n = n + 1 else break end
    end
    return last, n
end

-- 在候选栏最后一个 segment 加提示
local function prompt(ctx, msg)
    local comp = ctx.composition
    if comp and not comp:empty() then comp:back().prompt = msg end
end

function M.func(key, env)
    local ctx, kc = env.engine.context, key.keycode
    -- 先拿到“上一轮”高亮候选的 preedit 及段数
    local cand    = ctx:get_selected_candidate()
    local preedit = cand and (cand.preedit or cand:get_genuine().preedit) or ""
    local segs    = 1
    for _ in preedit:gmatch("[%'%s]") do segs = segs + 1 end
    -- 本次按键字符（只关心字母 / 分隔符）
    local ch
    if kc >= 0x61 and kc <= 0x7A then -- a~z
        ch = string.char(kc)
    elseif kc == 0x27 then            -- '
        ch = "'"
    elseif kc == 0x20 then            -- space
        ch = " "
    end
    -- ① 连续声母限制：第 MAX_REPEAT 个同声母直接拦截
    if ch and kc >= 0x61 and kc <= 0x7A then
        local nxt         = ctx.input .. ch
        local last, rep_n = tail_rep(nxt)
        if last:match(INITIALS) and rep_n > MAX_REPEAT then
            prompt(ctx, "  〔已超最大重复声母〕")
            return ACCEPT
        end
    end
    -- ② 分段限制：第 MAX_SEGMENTS 段拦截
    local segs_after = segs
    if ch == "'" or ch == " " then segs_after = segs + 1 end
    if segs_after >= MAX_SEGMENTS and kc >= 0x61 and kc <= 0x7A then
        prompt(ctx, "  〔已超最大输入长度〕")
        return ACCEPT
    end
    return PASS
end

return M