-- Migration 001: users table
-- Mirrors GoTrue auth.users — populated by trigger on first OIDC login.

-- ── Enums ─────────────────────────────────────────────────────────────────────

CREATE TYPE public.language_code AS ENUM ('en', 'es');
CREATE TYPE public.avatar_type   AS ENUM ('initials', 'emoji', 'upload');

-- ── Table ─────────────────────────────────────────────────────────────────────

CREATE TABLE public.users (
    id           uuid        PRIMARY KEY,  -- matches auth.users.id (GoTrue UUID)
    email        text        NOT NULL,
    display_name text        NOT NULL DEFAULT '',
    language     public.language_code NOT NULL DEFAULT 'en',
    avatar_type  public.avatar_type   NOT NULL DEFAULT 'initials',
    avatar_emoji text        NULL,
    avatar_url   text        NULL,         -- signed URL from Supabase Storage
    created_at   timestamptz NOT NULL DEFAULT now(),
    updated_at   timestamptz NOT NULL DEFAULT now()
);

ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;

-- ── updated_at trigger ────────────────────────────────────────────────────────

CREATE OR REPLACE FUNCTION public.set_updated_at()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
    NEW.updated_at = now();
    RETURN NEW;
END;
$$;

CREATE TRIGGER users_set_updated_at
    BEFORE UPDATE ON public.users
    FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();

-- ── Sync trigger: GoTrue auth.users → public.users on first OIDC login ────────
-- GoTrue inserts into auth.users after a successful Keycloak OIDC exchange.
-- We mirror display_name and detect language from raw_user_meta_data claims.

CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
DECLARE
    v_display_name text;
    v_language     public.language_code;
    v_raw          jsonb;
BEGIN
    v_raw := NEW.raw_user_meta_data;

    -- Build display name: full_name > name > email prefix
    v_display_name := COALESCE(
        NULLIF(trim(v_raw->>'full_name'), ''),
        NULLIF(trim(v_raw->>'name'), ''),
        split_part(NEW.email, '@', 1)
    );

    -- Detect language from OIDC locale claim; default en
    v_language := CASE
        WHEN v_raw->>'locale' ILIKE 'es%' THEN 'es'::public.language_code
        ELSE 'en'::public.language_code
    END;

    INSERT INTO public.users (id, email, display_name, language)
    VALUES (NEW.id, NEW.email, v_display_name, v_language)
    ON CONFLICT (id) DO UPDATE
        SET email        = EXCLUDED.email,
            -- Preserve user-set display name; only backfill if still empty
            display_name = CASE
                WHEN public.users.display_name = '' THEN EXCLUDED.display_name
                ELSE public.users.display_name
            END;

    RETURN NEW;
END;
$$;

CREATE TRIGGER on_auth_user_created
    AFTER INSERT ON auth.users
    FOR EACH ROW EXECUTE FUNCTION public.handle_new_user();
