-- Fix Discord username generation by reading from auth.identities
CREATE OR REPLACE FUNCTION public.handle_new_user()
RETURNS trigger
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path TO 'public', 'auth'
AS $$
DECLARE
  v_username TEXT;
  v_display_name TEXT;
  v_email TEXT;
  v_provider TEXT;
  v_username_attempt INTEGER := 0;
  v_max_attempts INTEGER := 10;
  v_unique_username TEXT;
  v_identity_data JSONB;
BEGIN
  -- Extract email and provider
  v_email := NEW.email;
  v_provider := NEW.raw_app_meta_data->>'provider';
  
  -- Smart username generation based on provider
  IF v_provider = 'google' THEN
    -- For Google: try email prefix, then name-based, then UUID fallback
    v_username := COALESCE(
      -- Email prefix (before @), sanitized
      LOWER(REGEXP_REPLACE(split_part(v_email, '@', 1), '[^a-z0-9_]', '_', 'g')),
      -- Name-based, sanitized
      LOWER(REGEXP_REPLACE(NEW.raw_user_meta_data->>'name', '[^a-z0-9_]', '_', 'g')),
      -- UUID fallback
      'user_' || substring(NEW.id::text, 1, 8)
    );
    v_display_name := NEW.raw_user_meta_data->>'name';
    
  ELSIF v_provider = 'discord' THEN
    -- For Discord: Extract data from auth.identities table
    SELECT identity_data INTO v_identity_data
    FROM auth.identities
    WHERE user_id = NEW.id AND provider = 'discord'
    LIMIT 1;
    
    IF v_identity_data IS NOT NULL THEN
      -- Extract username from full_name (preferred) or name without discriminator
      v_username := COALESCE(
        LOWER(REGEXP_REPLACE(v_identity_data->>'full_name', '[^a-z0-9_]', '_', 'g')),
        LOWER(REGEXP_REPLACE(split_part(v_identity_data->>'name', '#', 1), '[^a-z0-9_]', '_', 'g')),
        'user_' || substring(NEW.id::text, 1, 8)
      );
      
      -- Extract display name from custom_claims.global_name (preferred) or full_name
      v_display_name := COALESCE(
        v_identity_data->'custom_claims'->>'global_name',
        v_identity_data->>'full_name',
        v_identity_data->>'name'
      );
      
      RAISE NOTICE 'Discord user data extracted: username=%, display_name=%', v_username, v_display_name;
    ELSE
      -- Fallback if identity data not found
      v_username := 'user_' || substring(NEW.id::text, 1, 8);
      v_display_name := NULL;
      RAISE WARNING 'Discord identity data not found for user %, using fallback', NEW.id;
    END IF;
    
  ELSE
    -- Manual signup or other providers
    v_username := COALESCE(
      NEW.raw_user_meta_data->>'username',
      'user_' || substring(NEW.id::text, 1, 8)
    );
    v_display_name := COALESCE(
      NEW.raw_user_meta_data->>'display_name',
      NEW.raw_user_meta_data->>'name'
    );
  END IF;
  
  -- Ensure username uniqueness by appending counter if needed
  v_unique_username := v_username;
  WHILE v_username_attempt < v_max_attempts LOOP
    BEGIN
      -- Try to insert with current username
      INSERT INTO public.profiles (
        user_id, 
        username, 
        display_name,
        oauth_provider
      )
      VALUES (
        NEW.id,
        v_unique_username,
        v_display_name,
        v_provider
      );
      
      -- If successful, exit loop
      EXIT;
      
    EXCEPTION WHEN unique_violation THEN
      -- Username taken, try next variant
      v_username_attempt := v_username_attempt + 1;
      
      IF v_username_attempt < v_max_attempts THEN
        v_unique_username := v_username || '_' || v_username_attempt;
      ELSE
        -- Final fallback to UUID if all attempts fail
        v_unique_username := 'user_' || substring(NEW.id::text, 1, 8);
      END IF;
    END;
  END LOOP;
  
  -- Log the final username for debugging
  RAISE NOTICE 'Created profile for user % with username %', NEW.id, v_unique_username;
  
  RETURN NEW;
END;
$$;

COMMENT ON FUNCTION public.handle_new_user IS 'Creates user profile on signup with smart username generation. For Discord, reads from auth.identities table.';