local _, addon = ...
local HLY = addon.HLY

-- One-button fishing: cast Fishing when idle, reel (INTERACTTARGET / soft-interact)
-- when a bobber is up. Two ways to trigger, both optional:
--   * a keybind (Key Bindings > HLYqol) — swapped by a secure state driver
--   * a configurable double-click (modifier + mouse button)
-- Casting/interacting from input is protected, so both route through secure
-- buttons + override bindings.
-- ponytail: reel uses INTERACTTARGET. If a different interact binding reels for
-- you, that's the one knob to change.

local HANDLER = "HLYFishingHandler"
local DCBTN = "HLYFishingButton"
local DOUBLE_MAX = 0.4
local DOUBLE_MIN = 0.05
local BUTTON_KEY = { LeftButton = "BUTTON1", RightButton = "BUTTON2" }

_G.BINDING_HEADER_HLYQOL = "HLYqol"
_G.BINDING_NAME_HLYQOL_FISHING = "Fishing: cast / reel (One Button)"

local function GetFishingSpellName()
    if not GetProfessions then return nil end
    local _, _, _, fishing = GetProfessions()
    if not fishing then return nil end
    return (GetProfessionInfo(fishing))  -- localized "Fishing"
end

local function ModifierDown(mod)
    if mod == "SHIFT" then return IsShiftKeyDown() end
    if mod == "CTRL" then return IsControlKeyDown() end
    if mod == "ALT" then return IsAltKeyDown() end
    return true  -- NONE
end

-- Keybind: secure state driver swaps the bound key synchronously with the channel
-- state, so it never recasts instead of reeling.
function HLY:ApplyFishingBinding()
    local h = _G[HANDLER]
    if not h or InCombatLockdown() then return end

    UnregisterStateDriver(h, "chan")
    h:Execute([[ self:ClearBindings() ]])

    if not self.db or not self.db.fishing or not self.db.fishing.enabled then return end
    local name = GetFishingSpellName()
    local key = GetBindingKey("HLYQOL_FISHING")
    if not name or not key then return end

    h:SetAttribute("key", key)
    h:SetAttribute("fishingName", name)
    RegisterStateDriver(h, "chan", "[channeling:" .. name .. "] channel; idle")
end

function HLY:SetupFishing()
    if self.fishingSetup then return end
    self.fishingSetup = true

    local h = _G[HANDLER] or CreateFrame("Frame", HANDLER, UIParent, "SecureHandlerStateTemplate")
    h:SetAttribute("_onstate-chan", [[
        self:ClearBindings()
        local key = self:GetAttribute("key")
        if not key or key == "" then return end
        if newstate == "channel" then
            self:SetBinding(true, key, "INTERACTTARGET")
        else
            self:SetBindingSpell(true, key, self:GetAttribute("fishingName"))
        end
    ]])

    local dcBtn = _G[DCBTN] or CreateFrame("Button", DCBTN, UIParent, "SecureActionButtonTemplate")
    dcBtn:Hide()

    local bindFrame = CreateFrame("Frame")
    bindFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
    bindFrame:RegisterEvent("UPDATE_BINDINGS")
    bindFrame:RegisterEvent("PLAYER_REGEN_ENABLED")
    bindFrame:SetScript("OnEvent", function() self:ApplyFishingBinding() end)

    -- Double-click mode: arm the chosen mouse button on a modified double-click.
    local lastClick
    local dcFrame = CreateFrame("Frame")
    dcFrame:RegisterEvent("GLOBAL_MOUSE_DOWN")
    dcFrame:SetScript("OnEvent", function(_, _, button)
        local db = self.db and self.db.fishing
        if not db or not db.doubleClick or InCombatLockdown() then return end

        if button ~= (db.button or "RightButton") or not ModifierDown(db.modifier or "NONE") then
            ClearOverrideBindings(dcBtn)
            lastClick = nil
            return
        end

        local now = GetTime()
        if lastClick and (now - lastClick) < DOUBLE_MAX and (now - lastClick) > DOUBLE_MIN
            and not (LootFrame and LootFrame:IsShown()) then
            lastClick = nil
            local name = GetFishingSpellName()
            if name then
                if IsMouselooking() then MouselookStop() end
                local key = BUTTON_KEY[db.button or "RightButton"]
                if UnitChannelInfo("player") == name then
                    SetOverrideBinding(dcBtn, true, key, "INTERACTTARGET")
                else
                    SetOverrideBindingSpell(dcBtn, true, key, name)
                end
            end
        else
            lastClick = now
            ClearOverrideBindings(dcBtn)
        end
    end)
end

-- LibHLYUI options pane (v2) ------------------------------------------------
local MODIFIERS = {
    { value = "NONE", text = "Kein" },
    { value = "SHIFT", text = "Shift" },
    { value = "CTRL", text = "Strg" },
    { value = "ALT", text = "Alt" },
}
local BUTTONS = {
    { value = "RightButton", text = "Rechtsklick" },
    { value = "LeftButton", text = "Linksklick" },
}

function HLY:BuildFishingOptions(tab)
    tab:Note("One-Button-Angeln: wirft die Angel aus und holt den Fisch ein (braucht Beruf Angeln + aktiven Interact-Key/Soft-Interact).")

    tab:Section("Tastenbelegung")
    tab:Checkbox({
        label = "Enable (Taste unter Tastenbelegung > HLYqol)",
        get = function() return self.db.fishing.enabled end,
        set = function(v) self.db.fishing.enabled = v self:ApplyFishingBinding() end,
    })

    tab:Section("Doppelklick")
    tab:Checkbox({
        label = "Enable",
        get = function() return self.db.fishing.doubleClick end,
        set = function(v) self.db.fishing.doubleClick = v end,
    })
    tab:Dropdown({
        label = "Modifier", values = MODIFIERS,
        get = function() return self.db.fishing.modifier end,
        set = function(v) self.db.fishing.modifier = v end,
    })
    tab:Dropdown({
        label = "Maustaste", values = BUTTONS,
        get = function() return self.db.fishing.button end,
        set = function(v) self.db.fishing.button = v end,
    })
end

addon.options = addon.options or {}
addon.options[#addon.options + 1] = {
    group = "Other", groupOrder = 800, name = "Fishing", order = 4, groupAsEntry = true,
    build = "BuildFishingOptions",
}
