/**
 * Base properties defined in the SQL schema of the ETL job for WebUserEvent.
 * From: https://github.com/suno-ai/suno-dagster/blob/main/src/assets/snowflake/raw_table/frontend/web_user_event/insert.sql
 *
 * The following properties are handled automatically by the logging infrastructure:
 * - sessionId (handled by logWebUserEvent)
 * - eventName (handled by TrackingEvent wrapper)
 */
export enum FeatureSessionType {
  Create = 'create',
  Edit = 'edit',
}

export type ContextualProperties = {
  userId: string | null;
  featureSessionId: string | null;
  featureSessionType: FeatureSessionType | null;
};

export interface BaseWebUserEventProperties extends ContextualProperties {
  actionName: string;
  /**
   * The type of principal object this event is about
   * Example: "song", "user", "playlist", "error_type"
   */
  principalObjectType?: string;

  /**
   * The value/ID of the principal object
   * Example: song ID, user ID, error message
   */
  principalObjectValue?: string;

  /**
   * Component or page context where the event occurred
   * Example: "create_page", "song_page", "library"
   */
  componentContext?: string;

  /**
   * Additional context data for the event
   * Can contain any JSON-serializable data specific to the event
   */
  context?: Record<string, any>;
}

type ExtraKeys<T, U> = Exclude<keyof T, keyof U>;

/**
 * Type helper to ensure an event type includes all base properties.
 * This enforces that events use the correct property names (e.g., principalObjectType not principal_object_type).
 * Use Omit to remove the invalid fields, then re-adding them with error message types, which makes TypeScript complain about those specific properties.
 *
 */
export type WithValidBaseWebUserEventProperties<T> = T extends any
  ? ExtraKeys<T, BaseWebUserEventProperties> extends never
    ? T
    : Omit<T, ExtraKeys<T, BaseWebUserEventProperties>> & {
        [K in ExtraKeys<
          T,
          BaseWebUserEventProperties
        >]: `❌ ERROR: '${K & string}' is not a valid property. Remove it or add to BaseWebUserEventProperties.`;
      }
  : never;
