-- Atomically transition timer between states (Active -> Completed/Expired/Cancelled)
-- KEYS[1]: Timer key
-- KEYS[2]: Timer stats key
-- KEYS[3]: Audit log stream key
-- ARGV[1]: New status
-- ARGV[2]: Current timestamp
-- ARGV[3]: Reason for transition
-- ARGV[4]: User/system ID

local timer_key = KEYS[1]
local stats_key = KEYS[2]
local audit_key = KEYS[3]

local new_status = ARGV[1]
local timestamp = tonumber(ARGV[2])
local reason = ARGV[3]
local actor_id = ARGV[4]

-- Get current timer data
local current_data = redis.call('GET', timer_key)
if not current_data then
    return {err = 'TIMER_NOT_FOUND'}
end

-- Parse current status (simplified - assumes JSON parsing)
-- For production, you'd want proper JSON parsing in Lua
local current_status_pattern = '"status"%s*:%s*"([^"]*)"'
local current_status = string.match(current_data, current_status_pattern)

-- Validate state transition
local valid_transitions = {
    Active = {Completed = true, Expired = true, Cancelled = true},
    Completed = {},
    Expired = {},
    Cancelled = {}
}

if not current_status or not valid_transitions[current_status] or not valid_transitions[current_status][new_status] then
    return {err = 'INVALID_TRANSITION', current_status = current_status, new_status = new_status}
end

-- Update timer data with new status
local updated_data = string.gsub(current_data, '"status"%s*:%s*"[^"]*"', '"status":"' .. new_status .. '"')
updated_data = string.gsub(updated_data, '"updated_at"%s*:%s*"[^"]*"', '"updated_at":"' .. timestamp .. '"')

-- Set with original TTL to maintain expiration
local ttl = redis.call('TTL', timer_key)
if ttl > 0 then
    redis.call('SETEX', timer_key, ttl, updated_data)
else
    redis.call('SET', timer_key, updated_data)
end

-- Update statistics
redis.call('HINCRBY', stats_key, 'transition_count', 1)
redis.call('HINCRBY', stats_key, 'status_' .. string.lower(new_status) .. '_count', 1)
redis.call('HINCRBY', stats_key, 'status_' .. string.lower(current_status) .. '_count', -1)
redis.call('HSET', stats_key, 'last_transition', timestamp)

-- Add to audit log stream
redis.call('XADD', audit_key, '*',
    'event', 'status_transition',
    'timer_key', timer_key,
    'from_status', current_status,
    'to_status', new_status,
    'reason', reason,
    'actor_id', actor_id,
    'timestamp', timestamp
)

-- Publish transition notification
redis.call('PUBLISH', 'timer_events', 
    string.format('{"event":"timer_transition","key":"%s","from":"%s","to":"%s","timestamp":%d}', 
                  timer_key, current_status, new_status, timestamp))

return {ok = 'TRANSITION_COMPLETE', from_status = current_status, to_status = new_status}