-- Chattyness User Initialization Functions
-- PostgreSQL 18
--
-- Functions to initialize new users with default props and avatars.
-- Load via: psql -f schema/functions/002_user_init.sql

\set ON_ERROR_STOP on

BEGIN;

-- =============================================================================
-- Initialize New User with Default Props and Avatar
-- =============================================================================
-- Called when a new user is created to give them:
--   1. All face-tagged server props in their inventory
--   2. A default avatar (slot 0) with the Face prop and all emotions configured
--
-- Note: active_avatars entry is NOT created here - it's created when the user
-- joins a realm for the first time (per-realm avatar state).
-- =============================================================================

CREATE OR REPLACE FUNCTION auth.initialize_new_user(p_user_id UUID)
RETURNS VOID AS $$
DECLARE
    v_avatar_id UUID;
    v_face_inventory_id UUID;
    v_neutral_inventory_id UUID;
    v_happy_inventory_id UUID;
    v_sad_inventory_id UUID;
    v_angry_inventory_id UUID;
    v_surprised_inventory_id UUID;
    v_thinking_inventory_id UUID;
    v_laughing_inventory_id UUID;
    v_crying_inventory_id UUID;
    v_love_inventory_id UUID;
    v_confused_inventory_id UUID;
    v_sleeping_inventory_id UUID;
    v_wink_inventory_id UUID;
    v_prop RECORD;
BEGIN
    -- Insert all face-tagged server props into user's inventory
    -- Note: inventory layer/position are only for content layer props (skin/clothes/accessories).
    -- Emotion props have default_emotion instead of default_layer, so they get NULL layer/position.
    FOR v_prop IN
        SELECT id, name, asset_path, default_layer, default_emotion, default_position, slug,
               is_transferable, is_portable, is_droppable
        FROM server.props
        WHERE tags @> ARRAY['face']
        AND is_active = true
    LOOP
        -- Use a local variable for the inserted inventory ID
        DECLARE
            v_new_inventory_id UUID;
        BEGIN
            INSERT INTO auth.inventory (
                user_id,
                server_prop_id,
                prop_name,
                prop_asset_path,
                layer,
                position,
                origin,
                is_transferable,
                is_portable,
                is_droppable
            )
            VALUES (
                p_user_id,
                v_prop.id,
                v_prop.name,
                v_prop.asset_path,
                v_prop.default_layer,  -- NULL for emotion props
                CASE WHEN v_prop.default_layer IS NOT NULL THEN v_prop.default_position ELSE NULL END,
                'server_library',
                v_prop.is_transferable,
                v_prop.is_portable,
                v_prop.is_droppable
            )
            RETURNING id INTO v_new_inventory_id;

            -- Track inventory IDs for avatar assignment based on slug
            CASE v_prop.slug
                WHEN 'face' THEN v_face_inventory_id := v_new_inventory_id;
                WHEN 'neutral' THEN v_neutral_inventory_id := v_new_inventory_id;
                WHEN 'smile' THEN v_happy_inventory_id := v_new_inventory_id;
                WHEN 'sad' THEN v_sad_inventory_id := v_new_inventory_id;
                WHEN 'angry' THEN v_angry_inventory_id := v_new_inventory_id;
                WHEN 'surprised' THEN v_surprised_inventory_id := v_new_inventory_id;
                WHEN 'thinking' THEN v_thinking_inventory_id := v_new_inventory_id;
                WHEN 'laughing' THEN v_laughing_inventory_id := v_new_inventory_id;
                WHEN 'crying' THEN v_crying_inventory_id := v_new_inventory_id;
                WHEN 'love' THEN v_love_inventory_id := v_new_inventory_id;
                WHEN 'confused' THEN v_confused_inventory_id := v_new_inventory_id;
                WHEN 'sleeping' THEN v_sleeping_inventory_id := v_new_inventory_id;
                WHEN 'wink' THEN v_wink_inventory_id := v_new_inventory_id;
                ELSE NULL;
            END CASE;
        END;
    END LOOP;

    -- Create default avatar (slot 0) with the Face prop in skin layer
    -- and all emotion props in their respective emotion slots at position 4 (center)
    INSERT INTO auth.avatars (
        user_id,
        name,
        slot_number,
        last_emotion,
        -- Content layer: Face goes in skin layer, center position
        l_skin_4,
        -- Emotion layers: Each emotion prop goes to its matching emotion at center position
        e_neutral_4,
        e_happy_4,
        e_sad_4,
        e_angry_4,
        e_surprised_4,
        e_thinking_4,
        e_laughing_4,
        e_crying_4,
        e_love_4,
        e_confused_4,
        e_sleeping_4,
        e_wink_4
    )
    VALUES (
        p_user_id,
        'Default',
        0,
        0, -- Start with neutral emotion
        v_face_inventory_id,
        v_neutral_inventory_id,
        v_happy_inventory_id,
        v_sad_inventory_id,
        v_angry_inventory_id,
        v_surprised_inventory_id,
        v_thinking_inventory_id,
        v_laughing_inventory_id,
        v_crying_inventory_id,
        v_love_inventory_id,
        v_confused_inventory_id,
        v_sleeping_inventory_id,
        v_wink_inventory_id
    )
    RETURNING id INTO v_avatar_id;

    -- Note: We don't create an active_avatars entry here because that's per-realm.
    -- The active_avatars entry will be created when the user first joins a realm.
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

COMMENT ON FUNCTION auth.initialize_new_user(UUID) IS
    'Initialize a new user with default props in inventory and a default avatar configuration';

-- =============================================================================
-- Trigger Function for User Registration
-- =============================================================================
-- Wrapper trigger function that calls initialize_new_user.
-- =============================================================================

CREATE OR REPLACE FUNCTION auth.initialize_new_user_trigger()
RETURNS TRIGGER AS $$
BEGIN
    PERFORM auth.initialize_new_user(NEW.id);
    RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

COMMENT ON FUNCTION auth.initialize_new_user_trigger() IS
    'Trigger function to initialize new users on registration';

COMMIT;
