-- Migration 032: Fix session_sequences drift (CF-816)
-- Problem: Retro-imported sessions with explicit session_number bypass the trigger,
--          leaving session_sequences.next_number behind the actual MAX(session_number).
--          Next auto-assigned number then collides with the unique index.
-- Fix: Make get_next_session_number() self-healing by always checking actual max.

-- Step 1: Replace the function with a self-healing version
CREATE OR REPLACE FUNCTION get_next_session_number(p_project TEXT)
RETURNS INTEGER AS $$
DECLARE
    v_seq_number INTEGER;
    v_max_number INTEGER;
    v_number INTEGER;
BEGIN
    -- Insert project if doesn't exist
    INSERT INTO projects (key, name) VALUES (p_project, p_project)
    ON CONFLICT (key) DO NOTHING;

    -- Insert sequence if doesn't exist
    INSERT INTO session_sequences (project, next_number)
    VALUES (p_project, 1)
    ON CONFLICT (project) DO NOTHING;

    -- Get the actual max session_number for this project (handles external inserts)
    SELECT COALESCE(MAX(session_number), 0) INTO v_max_number
    FROM sessions
    WHERE project = p_project;

    -- Sync sequence forward if it fell behind (self-healing)
    UPDATE session_sequences
    SET next_number = GREATEST(next_number, v_max_number + 1),
        last_updated = NOW()
    WHERE project = p_project;

    -- Now atomically increment and return
    UPDATE session_sequences
    SET next_number = next_number + 1,
        last_updated = NOW()
    WHERE project = p_project
    RETURNING next_number - 1 INTO v_number;

    RETURN v_number;
END;
$$ LANGUAGE plpgsql;

-- Step 2: Sync all existing sequences to match actual data
UPDATE session_sequences sq
SET next_number = GREATEST(sq.next_number, sub.actual_max + 1),
    last_updated = NOW()
FROM (
    SELECT project, COALESCE(MAX(session_number), 0) AS actual_max
    FROM sessions
    WHERE project IS NOT NULL
    GROUP BY project
) sub
WHERE sq.project = sub.project
  AND sq.next_number <= sub.actual_max;
