-- 1. Identify it uniquely (Fresh ID forces macOS to update the hover title)
GeminiMonitorItem = hs.menubar.new(true, "GeminiMonitorV3")

-- 2. Set the hover text (Tooltip)
if GeminiMonitorItem then
    GeminiMonitorItem:setTooltip("Gemini Usage Monitor")
end

local JSON_KEY_PATH = os.getenv("HOME") .. "/.hammerspoon/gcp-key.json"
local PROJECT_ID = "gen-lang-client-0842463959" 
local UPDATE_INTERVAL = 300 

-- 3. Setup the Icon
-- "NSActionTemplate" is the standard 'Gear' icon
local geminiStar = hs.image.imageFromName("NSActionTemplate")

if geminiStar then
    -- 'template' allows the icon to switch between black and white for Dark Mode
    geminiStar:template(true) 
    GeminiMonitorItem:setIcon(geminiStar)
end

-- 2026 Flash Preview Pricing
local PRICING_ESTIMATES = {
    ["Gemini 3 Flash Preview"] = 0.0010,
    ["Gemini 3.1 Pro"]         = 0.0450,
    ["Gemini 2.0 Ultra"]       = 0.1500
}
local selectedModel = "Gemini 3 Flash Preview"

local stats = {
    requests = 0,
    lastUpdate = "Never"
}

local authToken = nil

-- POPUP ON LOAD
hs.alert.show("GeminiMonitor Loaded", 2)

local function getAccessToken(callback)
    local keyFile = io.open(JSON_KEY_PATH, "r")
    if not keyFile then return end
    local keyData = hs.json.decode(keyFile:read("*all"))
    keyFile:close()
    local now = os.time()
    local header = hs.base64.encode(hs.json.encode({alg="RS256", typ="JWT"}))
    local claim = hs.base64.encode(hs.json.encode({iss=keyData.client_email, scope="https://www.googleapis.com/auth/monitoring.read", aud="https://oauth2.googleapis.com/token", exp=now+3600, iat=now}))
    local sign_cmd = string.format("echo -n '%s' | openssl dgst -sha256 -sign <(echo '%s') -binary | openssl base64", header.."."..claim, keyData.private_key)
    hs.task.new("/bin/bash", function(c, out, e)
        local sig = out:gsub("%s+", ""):gsub("/", "_"):gsub("+", "-"):gsub("=", "")
        hs.http.asyncPost("https://oauth2.googleapis.com/token", "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion="..header.."."..claim.."."..sig, {["Content-Type"]="application/x-www-form-urlencoded"}, function(s, b)
            local res = hs.json.decode(b)
            if res and res.access_token then callback(res.access_token) end
        end)
    end, {"-c", sign_cmd}):start()
end

local function updateUsage()
    if not authToken then
        getAccessToken(function(token) authToken = token; updateUsage() end)
        return
    end

    local endTime = os.date("!%Y-%m-%dT%H:%M:%SZ")
    local startTime = os.date("!%Y-%m-%dT%H:%M:%SZ", os.time() - 86400)
    
    local filter = 'resource.type="consumed_api" AND metric.type="serviceruntime.googleapis.com/api/request_count" AND resource.labels.service="generativelanguage.googleapis.com"'
    local url = string.format("https://monitoring.googleapis.com/v3/projects/%s/timeSeries?filter=%s&interval.startTime=%s&interval.endTime=%s", 
                PROJECT_ID, hs.http.encodeForQuery(filter), startTime, endTime)

    hs.http.asyncGet(url, {Authorization = "Bearer "..authToken}, function(status, body)
        if status ~= 200 then return end
        local data = hs.json.decode(body)
        local r = 0
        if data.timeSeries then
            for _, s in ipairs(data.timeSeries) do
                for _, p in ipairs(s.points) do r = r + (tonumber(p.value.int64Value) or 0) end
            end
        end

        stats.requests = r
        stats.lastUpdate = os.date("%H:%M")
        
        local estCost = r * PRICING_ESTIMATES[selectedModel]
        GeminiMonitorItem:setTitle(string.format(" %d ($%0.3f)", r, estCost))
    end)
end

GeminiMonitorItem:setMenu(function()
    return {
        { title = "GEMINI FLASH MONITOR", disabled = true },
        { title = "Project: " .. PROJECT_ID, disabled = true },
        { title = "-" },
        { title = "24H Requests: " .. stats.requests },
        { title = string.format("Est. Cost:   $%0.4f", stats.requests * PRICING_ESTIMATES[selectedModel]) },
        { title = "-" },
        { title = "ACTIVE MODEL:", disabled = true },
        { title = "Gemini 3 Flash Preview", checked = (selectedModel == "Gemini 3 Flash Preview"), fn = function() selectedModel = "Gemini 3 Flash Preview"; updateUsage() end },
        { title = "Gemini 3.1 Pro", checked = (selectedModel == "Gemini 3.1 Pro"), fn = function() selectedModel = "Gemini 3.1 Pro"; updateUsage() end },
        { title = "-" },
        { title = "Refresh Now", fn = updateUsage },
        { title = "Last Sync: " .. stats.lastUpdate, disabled = true }
    }
end)

updateUsage()
if GeminiTimer then GeminiTimer:stop() end
GeminiTimer = hs.timer.doEvery(UPDATE_INTERVAL, updateUsage)
