local addonTable = select(2, ...)
---@type MK
local MK = addonTable.MK
local core = addonTable

core.MeetingStoneFeedback = core.MeetingStoneFeedback or {}
local MeetingStoneFeedback = core.MeetingStoneFeedback
local MeetingStoneConstants = core.MeetingStoneConstants or {}
local MEETINGSTONE_ICON_EYE_SIZE = MeetingStoneConstants.MEETINGSTONE_ICON_EYE_SIZE
local MEETINGSTONE_ICON_EYE_HOST_SIZE = MeetingStoneConstants.MEETINGSTONE_ICON_EYE_HOST_SIZE
local MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE = MeetingStoneConstants.MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE
local MEETINGSTONE_ICON_EYE_BACKGROUND_MASK = MeetingStoneConstants.MEETINGSTONE_ICON_EYE_BACKGROUND_MASK
local MEETINGSTONE_EMPTY_EYE_FADE_DURATION = MeetingStoneConstants.MEETINGSTONE_EMPTY_EYE_FADE_DURATION
local MeetingStoneBridge = core.MeetingStoneBridge or {}

local TryLoadQueueStatusFrameUI = MeetingStoneBridge.TryLoadQueueStatusFrameUI

local function CreateMeetingStoneSuccessEye(parent)
    if not parent then
        return nil
    end
    if parent.mkMeetingStoneSuccessEye then
        return parent.mkMeetingStoneSuccessEye
    end

    local eye
    if TryLoadQueueStatusFrameUI() then
        local ok, created = pcall(CreateFrame, "Frame", nil, parent, "EyeTemplate")
        if ok and created and created.StartFoundAnimationInit then
            eye = created
            local eyeSize = parent and parent.mkMeetingStoneEyeSize or MEETINGSTONE_ICON_EYE_SIZE
            eye:SetSize(eyeSize, eyeSize)
            eye:SetPoint("CENTER", parent, "CENTER", 0, 0)
            eye:SetFrameLevel(parent:GetFrameLevel() + 50)
            eye:Hide()
        end
    end

    parent.mkMeetingStoneSuccessEye = eye
    return eye
end

local function StartMeetingStoneEmptyApplicantEyeLoop(eye)
    if not eye then
        return false
    end

    local nativeEye = eye.Eye or eye
    if nativeEye.StartSearchingAnimation then
        eye.mkMeetingStoneEyeLooping = true
        pcall(nativeEye.StartSearchingAnimation, nativeEye)
        return true
    end
    if nativeEye.StartFoundAnimationLoop then
        eye.mkMeetingStoneEyeLooping = true
        pcall(nativeEye.StartFoundAnimationLoop, nativeEye)
        return true
    end
    if eye.StartSearchingAnimation then
        eye.mkMeetingStoneEyeLooping = true
        pcall(eye.StartSearchingAnimation, eye)
        return true
    end
    if eye.StartFoundAnimationLoop then
        eye.mkMeetingStoneEyeLooping = true
        pcall(eye.StartFoundAnimationLoop, eye)
        return true
    end
    return false
end

function MK:GetMeetingStoneEyeParent()
    local frame = self.mainWindow
    local portraitContainer = frame and frame.PortraitContainer
    local parent = portraitContainer or frame
    local anchor = portraitContainer and portraitContainer.portrait or parent
    if not parent then
        local widgets = self.widgets
        return widgets and (widgets.root or widgets.MSRightPanel)
    end

    if not parent.mkMeetingStoneEyeHost then
        local host = CreateFrame("Frame", nil, parent)
        host:SetFrameLevel((parent.GetFrameLevel and parent:GetFrameLevel() or 0) + 30)
        host.mkMeetingStoneEyeSize = MEETINGSTONE_ICON_EYE_SIZE

        local background = host:CreateTexture(nil, "BACKGROUND")
        background:SetPoint("CENTER")
        background:SetTexture("Interface\\Buttons\\WHITE8X8")
        background:SetVertexColor(0, 0, 0, 1)
        if host.CreateMaskTexture and background.AddMaskTexture then
            local mask = host:CreateMaskTexture()
            mask:SetTexture(MEETINGSTONE_ICON_EYE_BACKGROUND_MASK, "CLAMPTOBLACKADDITIVE", "CLAMPTOBLACKADDITIVE")
            mask:SetPoint("CENTER", background, "CENTER", 0, 0)
            mask:SetSize(MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE, MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE)
            pcall(background.AddMaskTexture, background, mask)
            host.BlackFillMask = mask
        elseif portraitContainer and portraitContainer.CircleMask and background.AddMaskTexture then
            pcall(background.AddMaskTexture, background, portraitContainer.CircleMask)
        end
        background:Hide()
        host.BlackFill = background

        parent.mkMeetingStoneEyeHost = host
    end

    parent.mkMeetingStoneEyeHost:ClearAllPoints()
    parent.mkMeetingStoneEyeHost:SetSize(MEETINGSTONE_ICON_EYE_HOST_SIZE, MEETINGSTONE_ICON_EYE_HOST_SIZE)
    parent.mkMeetingStoneEyeHost:SetPoint("CENTER", anchor, "CENTER", 0, 0)
    if parent.mkMeetingStoneEyeHost.BlackFill then
        parent.mkMeetingStoneEyeHost.BlackFill:SetSize(MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE, MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE)
    end
    if parent.mkMeetingStoneEyeHost.BlackFillMask then
        parent.mkMeetingStoneEyeHost.BlackFillMask:SetSize(MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE, MEETINGSTONE_ICON_EYE_BACKGROUND_SIZE)
    end

    return parent.mkMeetingStoneEyeHost
end

function MK:ShowMeetingStoneEmptyApplicantEye(playSound, playInitial)
    local parent = self:GetMeetingStoneEyeParent()
    local eye = CreateMeetingStoneSuccessEye(parent)
    if not eye then
        return
    end

    eye:ClearAllPoints()
    eye:SetPoint("CENTER", parent, "CENTER", 0, 0)
    eye:SetSize(parent.mkMeetingStoneEyeSize or MEETINGSTONE_ICON_EYE_SIZE, parent.mkMeetingStoneEyeSize or MEETINGSTONE_ICON_EYE_SIZE)
    eye:SetAlpha(1)
    eye:SetScale(1)
    if parent.BlackFill then
        parent.BlackFill:Show()
    end
    parent:Show()
    eye:Show()

    if eye.mkFadeAnimation then
        eye.mkFadeAnimation:Stop()
    end
    if eye.mkMeetingStoneEyeLooping then
        return
    end

    if eye.StopAnimating then
        pcall(eye.StopAnimating, eye)
    end

    StartMeetingStoneEmptyApplicantEyeLoop(eye)
end

function MK:SetMeetingStoneQueueStatusGlow(enabled)
    local parent = self:GetMeetingStoneEyeParent()
    local eye = parent and parent.mkMeetingStoneSuccessEye
    if not eye then
        return
    end

    if eye.SetGlowLock then
        pcall(eye.SetGlowLock, eye, "mk-meetingstone-applicant", enabled == true, 3)
        return
    end

    if _G.QueueStatusButton and _G.QueueStatusButton.SetGlowLock then
        pcall(_G.QueueStatusButton.SetGlowLock, _G.QueueStatusButton, "mk-meetingstone-applicant", enabled == true, 3)
        return
    end

    local highlight = eye.EyeHighlightAnim
    if not highlight then
        return
    end

    if enabled then
        if not highlight:IsPlaying() then
            highlight:Play()
        end
    elseif highlight:IsPlaying() then
        highlight:Stop()
    end
end

function MK:FadeOutMeetingStoneEmptyApplicantEye()
    local parent = self:GetMeetingStoneEyeParent()
    local eye = parent and parent.mkMeetingStoneSuccessEye
    if not eye or not eye:IsShown() then
        return
    end

    self:SetMeetingStoneQueueStatusGlow(false)
    eye.mkMeetingStoneEyeLooping = nil
    if not eye.mkFadeAnimation then
        local fade = eye:CreateAnimationGroup()
        local alpha = fade:CreateAnimation("Alpha")
        alpha:SetOrder(1)
        alpha:SetDuration(MEETINGSTONE_EMPTY_EYE_FADE_DURATION)
        alpha:SetFromAlpha(1)
        alpha:SetToAlpha(0)
        alpha:SetSmoothing("IN")
        fade:SetScript("OnFinished", function()
            local nativeEye = eye.Eye or eye
            if nativeEye.StopAnimating then
                pcall(nativeEye.StopAnimating, nativeEye)
            elseif eye.StopAnimating then
                pcall(eye.StopAnimating, eye)
            end
            eye:SetAlpha(1)
            eye:SetScale(1)
            eye:Hide()
            if parent.BlackFill then
                parent.BlackFill:Hide()
            end
        end)
        eye.mkFadeAnimation = fade
    end

    eye.mkFadeAnimation:Stop()
    eye.mkFadeAnimation:Play()
end

function MK:StopMeetingStoneCreateSuccessFeedback()
    local parent = self:GetMeetingStoneEyeParent()
    local eye = parent and parent.mkMeetingStoneSuccessEye
    if not eye then
        return
    end

    self:SetMeetingStoneQueueStatusGlow(false)
    eye.mkMeetingStoneEyeLooping = nil
    if eye.mkFadeAnimation then
        eye.mkFadeAnimation:Stop()
    end
    local nativeEye = eye.Eye or eye
    if nativeEye.StopAnimating then
        pcall(nativeEye.StopAnimating, nativeEye)
    elseif eye.StopAnimating then
        pcall(eye.StopAnimating, eye)
    end
    eye:SetAlpha(1)
    eye:SetScale(1)
    eye:Hide()
    if parent.BlackFill then
        parent.BlackFill:Hide()
    end
end

function MK:UpdateMeetingStoneEmptyApplicantEye(applicantRowsCount, rawApplicantCount)
    local hasActiveEntry = false
    if C_LFGList and C_LFGList.HasActiveEntryInfo then
        local ok, activeEntry = pcall(C_LFGList.HasActiveEntryInfo)
        hasActiveEntry = ok and activeEntry == true
    end
    if not hasActiveEntry then
        self:FadeOutMeetingStoneEmptyApplicantEye()
        return
    end

    if rawApplicantCount == nil and C_LFGList and C_LFGList.GetApplicants then
        local ok, applicants = pcall(C_LFGList.GetApplicants)
        rawApplicantCount = ok and type(applicants) == "table" and #applicants or 0
    end

    self:ShowMeetingStoneEmptyApplicantEye(false, false)
    self:SetMeetingStoneQueueStatusGlow((rawApplicantCount or 0) > 0)
end

function MK:PlayMeetingStoneCreateSuccessFeedback()
    self:ShowMeetingStoneEmptyApplicantEye(true, true)
end


MeetingStoneFeedback.CreateSuccessEye = CreateMeetingStoneSuccessEye
MeetingStoneFeedback.StartEmptyApplicantEyeLoop = StartMeetingStoneEmptyApplicantEyeLoop
