// src/tests/utils/mockFactories.ts
import {
  UserProfile,
  User,
  Flyer,
  Store,
  SuggestedCorrection,
  Brand,
  Category,
  FlyerItem,
  MasterGroceryItem,
  ShoppingList,
  ShoppingListItem,
  Achievement,
  UserAchievement,
  Budget,
  SpendingByCategory,
  Recipe,
  RecipeIngredient,
  RecipeComment,
  ActivityLogItem,
  DietaryRestriction,
  UserDietaryRestriction,
  Appliance,
  UserAppliance,
  Notification,
  UnmatchedFlyerItem,
  AdminUserView,
  WatchedItemDeal,
  LeaderboardUser,
  UserWithPasswordHash,
  Profile,
  Address,
  MenuPlan,
  PlannedMeal,
  PantryItem,
  Product,
  ShoppingTrip,
  ShoppingTripItem,
  Receipt,
  ReceiptItem,
  SearchQuery,
  ProcessingStage,
  UserAlert,
  UserSubmittedPrice,
  RecipeRating,
  Tag,
  PantryLocation,
  DealItem,
  ItemPriceHistory,
  HistoricalPriceDataPoint,
  ReceiptDeal,
  RecipeCollection,
  SharedShoppingList,
  MostFrequentSaleItem,
  PantryRecipe,
  RecommendedRecipe,
  UnitPrice,
  Source,
} from '../../types';
import type { AppStats } from '../../services/apiClient';

// --- ID Generator for Deterministic Mocking ---
let idCounter = 0;

/**
 * Generates a sequential number for deterministic IDs in tests.
 */
const getNextId = () => ++idCounter;

/**
 * Resets the ID counter. Call this in `beforeEach` in your test setup
 * to ensure tests are isolated.
 *
 * @example
 * beforeEach(() => {
 *   resetMockIds();
 * });
 */
export const resetMockIds = () => {
  idCounter = 0;
};
// --- End ID Generator ---

/**
 * Creates a mock User object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe User object.
 */
export const createMockUser = (overrides: Partial<User> = {}): User => {
  // Generate a deterministic, valid UUID-like string for mock user IDs.
  // This prevents database errors in integration tests where a UUID is expected.
  const userId =
    overrides.user_id ?? `00000000-0000-0000-0000-${String(getNextId()).padStart(12, '0')}`;

  const defaultUser: User = {
    user_id: userId,
    email: `${userId}@example.com`,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultUser, ...overrides };
};

/**
 * Creates a mock UserProfile object for use in tests, ensuring type safety.
 *
 * @param overrides - An object containing properties to override the default mock values.
 *                    This allows for easy customization of the mock user for specific test cases.
 *                    For example: `createMockUserProfile({ role: 'admin', points: 500 })`
 * @returns A complete and type-safe UserProfile object.
 */
export const createMockUserProfile = (
  overrides: Partial<Omit<UserProfile, 'user'>> & { user?: Partial<User> } = {},
): UserProfile => {
  // The user object is the source of truth for user_id and email.
  const user = createMockUser(overrides.user);

  const defaultProfile: UserProfile = {
    role: 'user',
    points: 0,
    full_name: 'Test User',
    avatar_url: null,
    preferences: {},
    address_id: null,
    created_by: null,
    address: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
    user,
  };

  // Exclude 'user' from overrides to prevent overwriting the complete user object with a partial one
  const { user: _, ...profileOverrides } = overrides;

  // Combine defaults, overrides, and the fully constructed user object.
  return { ...defaultProfile, ...profileOverrides, user };
};

/**
 * Creates a mock Store object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Store object.
 */
export const createMockStore = (overrides: Partial<Store> = {}): Store => {
  const storeId = overrides.store_id ?? getNextId();

  const defaultStore: Store = {
    store_id: storeId,
    name: 'Mock Store',
    logo_url: null,
    created_by: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultStore, ...overrides };
};

/**
 * Creates a mock Flyer object for use in tests, ensuring type safety.
 *
 * @param overrides - An object containing properties to override the default mock values,
 *                    including nested properties for the `store`.
 *                    e.g., `createMockFlyer({ item_count: 50, store: { name: 'Walmart' } })`
 * @returns A complete and type-safe Flyer object.
 */
export const createMockFlyer = (
  overrides: Omit<Partial<Flyer>, 'store'> & { store?: Partial<Store> } = {},
): Flyer => {
  const flyerId = overrides.flyer_id ?? getNextId();

  // Ensure the store_id is consistent between the flyer and the nested store object
  const store = createMockStore({
    ...overrides.store,
    // Prioritize the top-level store_id if provided
    store_id: overrides.store_id ?? overrides.store?.store_id,
  });

  const baseUrl = 'https://example.com'; // A reasonable default for tests

  // Determine the final file_name to generate dependent properties from.
  const fileName = overrides.file_name ?? `flyer-${flyerId}.jpg`;

  // A simple hash function for mock checksum generation.
  const generateMockChecksum = (str: string) => {
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = (hash << 5) - hash + char;
      hash |= 0; // Convert to 32bit integer
    }
    return `mock-checksum-${Math.abs(hash).toString(16)}`;
  };

  const defaultFlyer: Flyer = {
    flyer_id: flyerId,
    file_name: fileName,
    image_url: `${baseUrl}/flyer-images/${fileName}`,
    icon_url: `${baseUrl}/flyer-images/icons/icon-${fileName.replace(/\.[^/.]+$/, '.webp')}`,
    checksum: generateMockChecksum(fileName),
    store_id: store.store_id,
    valid_from: new Date().toISOString().split('T')[0],
    valid_to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], // 7 days from now
    store_address: '123 Main St, Anytown, USA',
    status: 'processed',
    item_count: 50,
    uploaded_by: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
    store,
  };

  const { store: _, ...flyerOverrides } = overrides;

  // Apply overrides. If checksum, file_name, etc., are in overrides, they will correctly replace the generated defaults.
  return { ...defaultFlyer, ...flyerOverrides };
};

/**
 * Creates a mock SuggestedCorrection object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe SuggestedCorrection object.
 */
export const createMockSuggestedCorrection = (
  overrides: Partial<SuggestedCorrection> = {},
): SuggestedCorrection => {
  const defaultCorrection: SuggestedCorrection = {
    suggested_correction_id: getNextId(),
    flyer_item_id: getNextId(),
    user_id: `user-${getNextId()}`,
    correction_type: 'price',
    suggested_value: '$9.99',
    status: 'pending',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultCorrection, ...overrides };
};

/**
 * Creates a mock Brand object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Brand object.
 */
export const createMockBrand = (overrides: Partial<Brand> = {}): Brand => {
  const brandId = overrides.brand_id ?? getNextId();

  const defaultBrand: Brand = {
    brand_id: brandId,
    name: `Brand ${brandId}`,
    logo_url: null,
    store_id: null,
    store_name: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultBrand, ...overrides };
};

/**
 * Creates a mock Category object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Category object.
 */
export const createMockCategory = (overrides: Partial<Category> = {}): Category => {
  const categoryId = overrides.category_id ?? getNextId();

  const defaultCategory: Category = {
    category_id: categoryId,
    name: `Category ${categoryId}`,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultCategory, ...overrides };
};

/**
 * Creates a mock Product object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 *                    Can optionally include `master_item` and `brand` to link IDs.
 * @returns A complete and type-safe Product object.
 */
export const createMockProduct = (
  overrides: Partial<Product> & {
    master_item?: Partial<MasterGroceryItem>;
    brand?: Partial<Brand>;
  } = {},
): Product => {
  const productId = overrides.product_id ?? getNextId();
  const masterItemId =
    overrides.master_item_id ?? overrides.master_item?.master_grocery_item_id ?? getNextId();
  const brandId = overrides.brand_id ?? overrides.brand?.brand_id; // brand is optional

  const defaultProduct: Product = {
    product_id: productId,
    master_item_id: masterItemId,
    brand_id: brandId,
    name: `Mock Product ${productId}`,
    description: 'A mock product description.',
    size: '100g',
    upc_code: `0000${productId}`.slice(-12),
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const { master_item: _, brand: __, ...itemOverrides } = overrides;

  return { ...defaultProduct, ...itemOverrides };
};

/**
 * Creates a mock FlyerItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe FlyerItem object.
 */
export const createMockFlyerItem = (
  overrides: Partial<FlyerItem> & { flyer?: Partial<Flyer> } = {},
): FlyerItem => {
  const flyerItemId = overrides.flyer_item_id ?? getNextId();
  const flyerId = overrides.flyer_id ?? overrides.flyer?.flyer_id ?? getNextId();

  const defaultItem: FlyerItem = {
    flyer_item_id: flyerItemId,
    flyer_id: flyerId,
    item: 'Mock Item',
    price_display: '$1.99',
    price_in_cents: 199,
    unit_price: null,
    quantity: 'each',
    view_count: 0,
    click_count: 0,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const { flyer: _, ...itemOverrides } = overrides;

  return { ...defaultItem, ...itemOverrides };
};

/**
 * Creates a mock Recipe object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Recipe object.
 */
export const createMockRecipe = (
  overrides: Omit<Partial<Recipe>, 'comments' | 'ingredients'> & {
    comments?: Partial<RecipeComment>[];
    ingredients?: Partial<RecipeIngredient>[];
  } = {},
): Recipe => {
  const recipeId = overrides.recipe_id ?? getNextId();

  const defaultRecipe: Recipe = {
    recipe_id: recipeId,
    user_id: `user-${getNextId()}`,
    name: `Mock Recipe ${recipeId}`,
    description: 'A delicious mock recipe.',
    instructions: '1. Mock the ingredients. 2. Mock the cooking. 3. Enjoy!',
    avg_rating: 4.5,
    rating_count: 50,
    fork_count: 10,
    status: 'public',
    prep_time_minutes: 15,
    cook_time_minutes: 30,
    servings: 4,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const {
    comments: commentsOverrides,
    ingredients: ingredientsOverrides,
    ...recipeOverrides
  } = overrides;
  const recipe = { ...defaultRecipe, ...recipeOverrides };

  if (commentsOverrides) {
    recipe.comments = commentsOverrides.map((comment) =>
      createMockRecipeComment({
        recipe_id: recipeId,
        ...comment,
      }),
    );
  }

  if (ingredientsOverrides) {
    recipe.ingredients = ingredientsOverrides.map((ingredient) =>
      createMockRecipeIngredient({
        recipe_id: recipeId,
        ...ingredient,
      }),
    );
  }

  return recipe;
};

/**
 * Creates a mock RecipeIngredient object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 *                    Can optionally include a `master_item` to link IDs.
 * @returns A complete and type-safe RecipeIngredient object.
 */
export const createMockRecipeIngredient = (
  overrides: Partial<RecipeIngredient> & { master_item?: Partial<MasterGroceryItem> } = {},
): RecipeIngredient => {
  const recipeIngredientId = overrides.recipe_ingredient_id ?? getNextId();
  const masterItemId =
    overrides.master_item_id ?? overrides.master_item?.master_grocery_item_id ?? getNextId();

  const defaultIngredient: RecipeIngredient = {
    recipe_ingredient_id: recipeIngredientId,
    recipe_id: getNextId(),
    master_item_id: masterItemId,
    quantity: 1,
    unit: 'cup',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const { master_item: _, ...itemOverrides } = overrides;

  return { ...defaultIngredient, ...itemOverrides };
};

/**
 * Creates a mock RecipeComment object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe RecipeComment object.
 */
export const createMockRecipeComment = (overrides: Partial<RecipeComment> = {}): RecipeComment => {
  const defaultComment: RecipeComment = {
    recipe_comment_id: getNextId(),
    recipe_id: getNextId(),
    user_id: `user-${getNextId()}`,
    content: 'This is a mock comment.',
    status: 'visible',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
    user_full_name: 'Mock User', // This was correct
    user_avatar_url: undefined,
  };

  return { ...defaultComment, ...overrides };
};

/**
 * Creates a mock PlannedMeal object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe PlannedMeal object.
 */
export const createMockPlannedMeal = (overrides: Partial<PlannedMeal> = {}): PlannedMeal => {
  const defaultMeal: PlannedMeal = {
    planned_meal_id: getNextId(),
    menu_plan_id: getNextId(),
    recipe_id: getNextId(),
    plan_date: new Date().toISOString().split('T')[0],
    meal_type: 'dinner',
    servings_to_cook: 4,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultMeal, ...overrides };
};

/**
 * Creates a mock MenuPlan object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe MenuPlan object.
 */
export const createMockMenuPlan = (
  overrides: Omit<Partial<MenuPlan>, 'planned_meals'> & {
    planned_meals?: Partial<PlannedMeal>[];
  } = {},
): MenuPlan => {
  const menuPlanId = overrides.menu_plan_id ?? getNextId();

  const defaultPlan: MenuPlan = {
    menu_plan_id: menuPlanId,
    user_id: `user-${getNextId()}`,
    name: 'Weekly Plan',
    start_date: new Date().toISOString().split('T')[0],
    end_date: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const { planned_meals: mealsOverrides, ...planOverrides } = overrides;
  const menuPlan = { ...defaultPlan, ...planOverrides };

  if (mealsOverrides) {
    menuPlan.planned_meals = mealsOverrides.map((meal) =>
      createMockPlannedMeal({
        menu_plan_id: menuPlanId,
        ...meal,
      }),
    );
  }

  return menuPlan;
};

/**
 * Creates a mock ActivityLogItem object for use in tests.
 * This factory handles the discriminated union nature of the ActivityLogItem type.
 * By default, it creates a 'flyer_processed' log item. You can override the 'action'
 * and 'details' to create other types of log items.
 *
 * @param overrides - An object containing properties to override the default mock values.
 *   e.g., `createMockActivityLogItem({ action: 'user_registered', details: { full_name: 'New User' } })`
 * @returns A complete and type-safe ActivityLogItem object.
 */
export const createMockActivityLogItem = (
  overrides: Partial<ActivityLogItem> = {},
): ActivityLogItem => {
  const action = overrides.action ?? 'flyer_processed';

  const baseLog = {
    activity_log_id: getNextId(),
    user_id: `user-${getNextId()}`,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  let specificLog: ActivityLogItem;

  // Create a default log based on the action, which can then be overridden.
  switch (action) {
    case 'recipe_created':
      specificLog = {
        ...baseLog,
        action: 'recipe_created',
        display_text: 'Created a new recipe: Mock Recipe.',
        icon: 'chef-hat',
        details: { recipe_id: 1, recipe_name: 'Mock Recipe' },
      };
      break;
    case 'user_registered':
      specificLog = {
        ...baseLog,
        action: 'user_registered',
        display_text: 'A new user has registered.',
        icon: 'user-plus',
        details: { full_name: 'New Mock User' },
      };
      break;
    case 'list_shared':
      specificLog = {
        ...baseLog,
        action: 'list_shared',
        display_text: 'A shopping list was shared.',
        icon: 'share-2',
        details: { list_name: 'Mock List', shopping_list_id: 1, shared_with_name: 'Another User' },
      };
      break;
    case 'recipe_favorited':
      specificLog = {
        ...baseLog,
        action: 'recipe_favorited',
        display_text: 'User favorited a recipe.',
        icon: 'heart',
        user_full_name: 'Mock User',
        details: { recipe_name: 'Mock Recipe' },
      };
      break;
    case 'flyer_processed':
    default:
      specificLog = {
        ...baseLog,
        action: 'flyer_processed',
        display_text: 'Processed a new flyer for Mock Store.',
        icon: 'file-check',
        details: { flyer_id: 1, store_name: 'Mock Store' },
      };
      break;
  }

  // Merge the generated log with any specific overrides provided.
  // This allows for deep merging of the 'details' object.
  return {
    ...specificLog,
    ...overrides,
    details: { ...specificLog.details, ...overrides.details },
  } as ActivityLogItem;
};

/**
 * Creates a mock Achievement object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Achievement object.
 */
export const createMockAchievement = (overrides: Partial<Achievement> = {}): Achievement => {
  const defaultAchievement: Achievement = {
    achievement_id: getNextId(),
    name: 'Mock Achievement',
    description: 'A great accomplishment.',
    icon: 'star',
    points_value: 10,
    created_at: new Date().toISOString(),
  };
  return { ...defaultAchievement, ...overrides };
};

/**
 * Creates a mock object representing a joined UserAchievement and Achievement for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe object representing the joined achievement data.
 */
export const createMockUserAchievement = (
  overrides: Partial<UserAchievement & Achievement> = {},
): UserAchievement & Achievement => {
  const achievementId = overrides.achievement_id ?? getNextId();
  const defaultUserAchievement: UserAchievement & Achievement = {
    user_id: `user-${getNextId()}`,
    achievement_id: achievementId,
    achieved_at: new Date().toISOString(),
    // from Achievement
    name: 'Mock User Achievement',
    description: 'An achievement someone earned.',
    icon: 'award',
    points_value: 20,
    created_at: new Date().toISOString(),
  };
  return { ...defaultUserAchievement, ...overrides };
};

/**
 * Creates a mock Budget object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Budget object.
 */
export const createMockBudget = (overrides: Partial<Budget> = {}): Budget => {
  const defaultBudget: Budget = {
    budget_id: getNextId(),
    user_id: `user-${getNextId()}`,
    name: 'Monthly Groceries',
    amount_cents: 50000,
    period: 'monthly',
    start_date: new Date().toISOString().split('T')[0],
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultBudget, ...overrides };
};

/**
 * Creates a mock SpendingByCategory object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe SpendingByCategory object.
 */
export const createMockSpendingByCategory = (
  overrides: Partial<SpendingByCategory> = {},
): SpendingByCategory => {
  const defaultSpending: SpendingByCategory = {
    category_id: getNextId(),
    category_name: 'Produce',
    total_spent_cents: 15000,
  };
  return { ...defaultSpending, ...overrides };
};

/**
 * Creates a mock MasterGroceryItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe MasterGroceryItem object.
 */
export const createMockMasterGroceryItem = (
  overrides: Partial<MasterGroceryItem> & { category?: Partial<Category> } = {},
): MasterGroceryItem => {
  // Ensure category_id is consistent between the item and the nested category object
  const category = createMockCategory({
    ...overrides.category,
    // Prioritize the top-level category_id if provided
    category_id: overrides.category_id ?? overrides.category?.category_id,
  });

  const defaultItem: MasterGroceryItem = {
    master_grocery_item_id: getNextId(),
    name: 'Mock Master Item',
    category_id: category.category_id,
    category_name: category.name,
    is_allergen: false,
    allergy_info: null,
    created_by: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const { category: _, ...itemOverrides } = overrides;

  return { ...defaultItem, ...itemOverrides };
};

/**
 * Creates a mock PantryItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 *                    Can optionally include a `master_item` to link IDs.
 * @returns A complete and type-safe PantryItem object.
 */
export const createMockPantryItem = (
  overrides: Partial<PantryItem> & { master_item?: Partial<MasterGroceryItem> } = {},
): PantryItem => {
  const pantryItemId = overrides.pantry_item_id ?? getNextId();

  const masterItemId =
    overrides.master_item_id ?? overrides.master_item?.master_grocery_item_id ?? getNextId();

  const defaultItem: PantryItem = {
    pantry_item_id: pantryItemId,
    user_id: `user-${getNextId()}`,
    master_item_id: masterItemId,
    quantity: 1,
    unit: 'each',
    updated_at: new Date().toISOString(),
  };

  const { master_item: _, ...itemOverrides } = overrides;

  return { ...defaultItem, ...itemOverrides };
};

/**
 * Creates a mock ShoppingList object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe ShoppingList object.
 */
export const createMockShoppingList = (
  overrides: Omit<Partial<ShoppingList>, 'items'> & {
    items?: (Partial<ShoppingListItem> & { master_item?: Partial<MasterGroceryItem> | null })[];
  } = {},
): ShoppingList => {
  const shoppingListId = overrides.shopping_list_id ?? getNextId();

  const defaultList: ShoppingList = {
    shopping_list_id: shoppingListId,
    user_id: `user-${getNextId()}`,
    name: 'My Mock List',
    items: [],
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  if (overrides.items) {
    defaultList.items = overrides.items.map((item) =>
      createMockShoppingListItem({
        shopping_list_id: shoppingListId,
        ...item,
      }),
    );
  }

  const { items: _, ...listOverrides } = overrides;

  return { ...defaultList, ...listOverrides };
};

/**
 * Creates a mock ShoppingListItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 *                    Can optionally include a `master_item` to link IDs and populate joined data.
 * @returns A complete and type-safe ShoppingListItem object.
 */
export const createMockShoppingListItem = (
  overrides: Partial<ShoppingListItem> & { master_item?: Partial<MasterGroceryItem> | null } = {},
): ShoppingListItem => {
  const shoppingListItemId = overrides.shopping_list_item_id ?? getNextId();
  const shoppingListId = overrides.shopping_list_id ?? getNextId();

  const masterItemId = overrides.master_item_id ?? overrides.master_item?.master_grocery_item_id;

  const defaultItem: ShoppingListItem = {
    shopping_list_item_id: shoppingListItemId,
    shopping_list_id: shoppingListId,
    custom_item_name: 'Mock Shopping List Item',
    quantity: 1,
    is_purchased: false, // This was correct
    added_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
    master_item_id: masterItemId,
  };

  const { master_item: masterItemOverride, ...itemOverrides } = overrides;
  const result = { ...defaultItem, ...itemOverrides };

  if (masterItemOverride && !result.master_item && masterItemOverride.name) {
    result.master_item = { name: masterItemOverride.name };
  }

  return result;
};

/**
 * Creates a mock ShoppingTripItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe ShoppingTripItem object.
 */
export const createMockShoppingTripItem = (
  overrides: Partial<ShoppingTripItem> & { master_item?: Partial<MasterGroceryItem> } = {},
): ShoppingTripItem => {
  const tripItemId = overrides.shopping_trip_item_id ?? getNextId();
  const masterItemId = overrides.master_item_id ?? overrides.master_item?.master_grocery_item_id;

  const defaultItem: ShoppingTripItem = {
    shopping_trip_item_id: tripItemId,
    shopping_trip_id: getNextId(),
    master_item_id: masterItemId,
    custom_item_name: masterItemId ? null : 'Custom Trip Item',
    master_item_name: masterItemId ? (overrides.master_item?.name ?? 'Mock Master Item') : null,
    quantity: 1,
    price_paid_cents: 199,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const { master_item: _, ...itemOverrides } = overrides;

  return { ...defaultItem, ...itemOverrides };
};

/**
 * Creates a mock ShoppingTrip object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe ShoppingTrip object.
 */
export const createMockShoppingTrip = (
  overrides: Omit<Partial<ShoppingTrip>, 'items'> & { items?: Partial<ShoppingTripItem>[] } = {},
): ShoppingTrip => {
  const tripId = overrides.shopping_trip_id ?? getNextId();

  const defaultTrip: ShoppingTrip = {
    shopping_trip_id: tripId,
    user_id: `user-${getNextId()}`,
    shopping_list_id: null,
    completed_at: new Date().toISOString(),
    total_spent_cents: 0,
    items: [],
    updated_at: new Date().toISOString(),
  };

  const { items: itemsOverrides, ...tripOverrides } = overrides;
  const trip = { ...defaultTrip, ...tripOverrides };

  if (itemsOverrides) {
    trip.items = itemsOverrides.map((item) =>
      createMockShoppingTripItem({ shopping_trip_id: tripId, ...item }),
    );
    if (overrides.total_spent_cents === undefined) {
      trip.total_spent_cents = trip.items.reduce(
        (total, item) => total + (item.price_paid_cents ?? 0),
        0,
      );
    }
  }

  return trip;
};

/**
 * Creates a mock ReceiptItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe ReceiptItem object.
 */
export const createMockReceiptItem = (overrides: Partial<ReceiptItem> = {}): ReceiptItem => {
  const defaultItem: ReceiptItem = {
    receipt_item_id: getNextId(),
    receipt_id: getNextId(),
    raw_item_description: 'Mock Receipt Item',
    quantity: 1,
    price_paid_cents: 199,
    master_item_id: null,
    product_id: null,
    status: 'unmatched',
    upc_code: null,
    line_number: null,
    match_confidence: null,
    is_discount: false,
    unit_price_cents: null,
    unit_type: null,
    added_to_pantry: false,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultItem, ...overrides };
};

/**
 * Creates a mock Receipt object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Receipt object.
 */
export const createMockReceipt = (
  overrides: Omit<Partial<Receipt>, 'items'> & { items?: Partial<ReceiptItem>[] } = {},
): Receipt => {
  const receiptId = overrides.receipt_id ?? getNextId();

  const defaultReceipt: Receipt = {
    receipt_id: receiptId,
    user_id: `user-${getNextId()}`,
    store_id: null,
    receipt_image_url: `/receipts/mock-receipt-${receiptId}.jpg`,
    transaction_date: new Date().toISOString(),
    total_amount_cents: null,
    status: 'pending',
    raw_text: null,
    processed_at: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  const { items: itemsOverrides, ...receiptOverrides } = overrides;
  const receipt = { ...defaultReceipt, ...receiptOverrides };

  if (itemsOverrides) {
    receipt.items = itemsOverrides.map((item) =>
      createMockReceiptItem({ receipt_id: receiptId, ...item }),
    );
  }

  return receipt;
};

/**
 * Creates a mock DietaryRestriction object for testing.
 * @param overrides - Optional properties to override the defaults.
 * @returns A mock DietaryRestriction object.
 */
export const createMockDietaryRestriction = (
  overrides: Partial<DietaryRestriction> = {},
): DietaryRestriction => {
  return {
    dietary_restriction_id: 1,
    name: 'Vegetarian',
    type: 'diet',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
    ...overrides,
  };
};

/**
 * Creates a mock DealItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe DealItem object.
 */
export const createMockDealItem = (overrides: Partial<DealItem> = {}): DealItem => {
  const defaultDealItem: DealItem = {
    item: 'Mock Deal Item',
    price_display: '$1.99',
    price_in_cents: 199,
    quantity: 'each',
    storeName: 'Mock Store',
    master_item_name: 'Mock Master Item',
    unit_price: null,
  };

  return { ...defaultDealItem, ...overrides };
};

/**
 * Creates a mock ItemPriceHistory object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe ItemPriceHistory object.
 */
export const createMockItemPriceHistory = (
  overrides: Partial<ItemPriceHistory> = {},
): ItemPriceHistory => {
  const defaultHistory: ItemPriceHistory = {
    item_price_history_id: getNextId(),
    master_item_id: getNextId(),
    summary_date: new Date().toISOString().split('T')[0],
    min_price_in_cents: 199,
    max_price_in_cents: 399,
    avg_price_in_cents: 299,
    data_points_count: 10,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultHistory, ...overrides };
};

/**
 * Creates a mock HistoricalPriceDataPoint object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe HistoricalPriceDataPoint object.
 */
export const createMockHistoricalPriceDataPoint = (
  overrides: Partial<HistoricalPriceDataPoint> = {},
): HistoricalPriceDataPoint => {
  const defaultPoint: HistoricalPriceDataPoint = {
    master_item_id: getNextId(),
    avg_price_in_cents: 250,
    summary_date: new Date().toISOString().split('T')[0],
  };
  return { ...defaultPoint, ...overrides };
};

/**
 * Creates a mock ReceiptDeal object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe ReceiptDeal object.
 */
export const createMockReceiptDeal = (overrides: Partial<ReceiptDeal> = {}): ReceiptDeal => {
  const defaultDeal: ReceiptDeal = {
    receipt_item_id: getNextId(),
    master_item_id: getNextId(),
    item_name: 'Mock Deal Item',
    price_paid_cents: 199,
    current_best_price_in_cents: 150,
    potential_savings_cents: 49,
    deal_store_name: 'Competitor Store',
    flyer_id: getNextId(),
  };
  return { ...defaultDeal, ...overrides };
};

/**
 * Creates a mock RecipeCollection object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe RecipeCollection object.
 */
export const createMockRecipeCollection = (
  overrides: Partial<RecipeCollection> = {},
): RecipeCollection => {
  const defaultCollection: RecipeCollection = {
    recipe_collection_id: getNextId(),
    user_id: `user-${getNextId()}`,
    name: 'My Favorite Recipes',
    description: 'A collection of mock recipes.',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultCollection, ...overrides };
};

/**
 * Creates a mock SharedShoppingList object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe SharedShoppingList object.
 */
export const createMockSharedShoppingList = (
  overrides: Partial<SharedShoppingList> = {},
): SharedShoppingList => {
  const defaultSharedList: SharedShoppingList = {
    shared_shopping_list_id: getNextId(),
    shopping_list_id: getNextId(),
    shared_by_user_id: `user-${getNextId()}`,
    shared_with_user_id: `user-${getNextId()}`,
    permission_level: 'view',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultSharedList, ...overrides };
};

/**
 * Creates a mock MostFrequentSaleItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe MostFrequentSaleItem object.
 */
export const createMockMostFrequentSaleItem = (
  overrides: Partial<MostFrequentSaleItem> = {},
): MostFrequentSaleItem => {
  const defaultItem: MostFrequentSaleItem = {
    master_item_id: getNextId(),
    item_name: 'Chicken Breast',
    sale_count: 25,
  };
  return { ...defaultItem, ...overrides };
};

/**
 * Creates a mock PantryRecipe object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe PantryRecipe object.
 */
export const createMockPantryRecipe = (overrides: Partial<PantryRecipe> = {}): PantryRecipe => {
  const defaultRecipe = createMockRecipe({ name: 'Pantry Special', ...overrides });
  const pantryRecipe: PantryRecipe = {
    ...defaultRecipe,
    missing_ingredients_count: 2,
    pantry_ingredients_count: 5,
  };
  return { ...pantryRecipe, ...overrides };
};

/**
 * Creates a mock RecommendedRecipe object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe RecommendedRecipe object.
 */
export const createMockRecommendedRecipe = (
  overrides: Partial<RecommendedRecipe> = {},
): RecommendedRecipe => {
  const defaultRecipe = createMockRecipe({ name: 'Highly Recommended', ...overrides });
  const recommendedRecipe: RecommendedRecipe = {
    ...defaultRecipe,
    recommendation_score: 0.85,
    reason: 'Based on your recent activity and pantry items.',
  };
  return { ...recommendedRecipe, ...overrides };
};

/**
 * Creates a mock UnitPrice object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe UnitPrice object.
 */
export const createMockUnitPrice = (overrides: Partial<UnitPrice> = {}): UnitPrice => {
  const defaultUnitPrice: UnitPrice = {
    value: 100,
    unit: 'g',
  };
  return { ...defaultUnitPrice, ...overrides };
};

/**
 * Creates a mock Source object for use in tests, typically for AI analysis results.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Source object.
 */
export const createMockSource = (overrides: Partial<Source> = {}): Source => {
  const defaultSource: Source = {
    uri: 'https://example.com/mock-source',
    title: 'Mock Source Title',
  };
  return { ...defaultSource, ...overrides };
};

/**
 * Creates a mock UserAlert object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe UserAlert object.
 */
export const createMockUserAlert = (overrides: Partial<UserAlert> = {}): UserAlert => {
  const defaultAlert: UserAlert = {
    user_alert_id: getNextId(),
    user_watched_item_id: getNextId(),
    alert_type: 'PRICE_BELOW',
    threshold_value: 499,
    is_active: true,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultAlert, ...overrides };
};

/**
 * Creates a mock UserSubmittedPrice object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe UserSubmittedPrice object.
 */
export const createMockUserSubmittedPrice = (
  overrides: Partial<UserSubmittedPrice> = {},
): UserSubmittedPrice => {
  const defaultPrice: UserSubmittedPrice = {
    user_submitted_price_id: getNextId(),
    user_id: `user-${getNextId()}`,
    master_item_id: getNextId(),
    store_id: getNextId(),
    price_in_cents: 299,
    photo_url: null,
    upvotes: 0,
    downvotes: 0,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultPrice, ...overrides };
};

/**
 * Creates a mock RecipeRating object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe RecipeRating object.
 */
export const createMockRecipeRating = (overrides: Partial<RecipeRating> = {}): RecipeRating => {
  const defaultRating: RecipeRating = {
    recipe_rating_id: getNextId(),
    recipe_id: getNextId(),
    user_id: `user-${getNextId()}`,
    rating: 5,
    comment: 'Great recipe!',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultRating, ...overrides };
};

/**
 * Creates a mock Tag object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Tag object.
 */
export const createMockTag = (overrides: Partial<Tag> = {}): Tag => {
  const tagId = overrides.tag_id ?? getNextId();
  const defaultTag: Tag = {
    tag_id: tagId,
    name: `Tag ${tagId}`,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultTag, ...overrides };
};

/**
 * Creates a mock PantryLocation object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe PantryLocation object.
 */
export const createMockPantryLocation = (
  overrides: Partial<PantryLocation> = {},
): PantryLocation => {
  const locationId = overrides.pantry_location_id ?? getNextId();
  const defaultLocation: PantryLocation = {
    pantry_location_id: locationId,
    user_id: `user-${getNextId()}`,
    name: `Location ${locationId}`,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };
  return { ...defaultLocation, ...overrides };
};

/**
 * Creates a mock AppStats object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe AppStats object.
 */
export const createMockAppStats = (overrides: Partial<AppStats> = {}): AppStats => {
  const defaultStats: AppStats = {
    userCount: 100,
    flyerCount: 50,
    flyerItemCount: 2000,
    storeCount: 5,
    pendingCorrectionCount: 0,
    recipeCount: 500,
  };
  return { ...defaultStats, ...overrides };
};

/**
 * Creates a mock UserDietaryRestriction object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 *                    Can optionally include `user` and `restriction` objects to link IDs.
 * @returns A complete and type-safe UserDietaryRestriction object.
 */
export const createMockUserDietaryRestriction = (
  overrides: Partial<UserDietaryRestriction> & {
    user?: Partial<User>;
    restriction?: Partial<DietaryRestriction>;
  } = {},
): UserDietaryRestriction => {
  const userId = overrides.user_id ?? overrides.user?.user_id ?? `user-${getNextId()}`;
  const restrictionId =
    overrides.restriction_id ?? overrides.restriction?.dietary_restriction_id ?? getNextId();

  const defaultUserRestriction: UserDietaryRestriction = {
    user_id: userId,
    restriction_id: restrictionId,
    created_at: new Date().toISOString(),
  };

  return { ...defaultUserRestriction, ...overrides };
};

/**
 * Creates a mock UserAppliance object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 *                    Can optionally include `user` and `appliance` objects to link IDs.
 * @returns A complete and type-safe UserAppliance object.
 */
export const createMockUserAppliance = (
  overrides: Partial<UserAppliance> & { user?: Partial<User>; appliance?: Partial<Appliance> } = {},
): UserAppliance => {
  const userId = overrides.user_id ?? overrides.user?.user_id ?? `user-${getNextId()}`;
  const applianceId = overrides.appliance_id ?? overrides.appliance?.appliance_id ?? getNextId();

  const defaultUserAppliance = {
    user_id: userId,
    appliance_id: applianceId,
    created_at: new Date().toISOString(),
  };

  // The 'as UserAppliance' cast is necessary because TypeScript can't guarantee that the spread of a Partial<T> results in a complete T.
  return { ...defaultUserAppliance, ...overrides } as UserAppliance;
};

/**
 * Creates a mock Address object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Address object.
 */
export const createMockAddress = (overrides: Partial<Address> = {}): Address => {
  const defaultAddress: Address = {
    address_id: getNextId(),
    address_line_1: '123 Mock St',
    city: 'Mockville',
    province_state: 'BC',
    postal_code: 'V8T 1A1',
    country: 'CA',
    // Optional fields
    address_line_2: null,
    latitude: null,
    longitude: null,
    location: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultAddress, ...overrides };
};

/**
 * Creates a mock UserWithPasswordHash object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe UserWithPasswordHash object.
 */
export const createMockUserWithPasswordHash = (
  overrides: Partial<UserWithPasswordHash> = {},
): UserWithPasswordHash => {
  const userId = overrides.user_id ?? `user-${getNextId()}`;

  const defaultUser: UserWithPasswordHash = {
    user_id: userId,
    email: `${userId}@example.com`,
    password_hash: 'hashed_password',
    failed_login_attempts: 0,
    last_failed_login: null,
    last_login_ip: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultUser, ...overrides };
};

/**
 * Creates a mock Profile object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Profile object.
 */
export const createMockProfile = (overrides: Partial<Profile> = {}): Profile => {
  const defaultProfile: Profile = {
    full_name: 'Mock Profile User',
    avatar_url: null,
    address_id: null,
    points: 0,
    role: 'user',
    preferences: {},
    created_by: null,
    updated_by: null,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultProfile, ...overrides };
};

/**
 * Creates a mock WatchedItemDeal object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe WatchedItemDeal object.
 */
export const createMockWatchedItemDeal = (
  overrides: Partial<WatchedItemDeal> = {},
): WatchedItemDeal => {
  const defaultDeal: WatchedItemDeal = {
    master_item_id: getNextId(),
    item_name: 'Mock Deal Item',
    best_price_in_cents: 599,
    store_name: 'Mock Store',
    flyer_id: getNextId(),
    valid_to: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000).toISOString(), // 5 days from now
  };

  return { ...defaultDeal, ...overrides };
};

/**
 * Creates a mock LeaderboardUser object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe LeaderboardUser object.
 */
export const createMockLeaderboardUser = (
  overrides: Partial<LeaderboardUser> = {},
): LeaderboardUser => {
  const userId = overrides.user_id ?? `user-${getNextId()}`;

  const defaultUser: LeaderboardUser = {
    user_id: userId,
    full_name: 'Leaderboard User',
    avatar_url: null,
    points: 500,
    rank: '10',
  };

  return { ...defaultUser, ...overrides };
};

/**
 * Creates a mock UnmatchedFlyerItem object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe UnmatchedFlyerItem object.
 */
export const createMockUnmatchedFlyerItem = (
  overrides: Partial<UnmatchedFlyerItem> = {},
): UnmatchedFlyerItem => {
  const defaultItem: UnmatchedFlyerItem = {
    unmatched_flyer_item_id: getNextId(),
    status: 'pending',
    reviewed_at: null,
    flyer_item_id: getNextId(),
    flyer_item_name: 'Mystery Product',
    price_display: '$?.??',
    flyer_id: getNextId(),
    store_name: 'Random Store',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultItem, ...overrides };
};

/**
 * Creates a mock AdminUserView object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe AdminUserView object.
 */
export const createMockAdminUserView = (overrides: Partial<AdminUserView> = {}): AdminUserView => {
  const userId = overrides.user_id ?? `user-${getNextId()}`;

  const defaultUserView: AdminUserView = {
    user_id: userId,
    email: `${userId}@example.com`,
    role: 'user',
    full_name: 'Mock User',
    avatar_url: null,
    created_at: new Date().toISOString(),
  };

  return { ...defaultUserView, ...overrides };
};

/**
 * Creates a mock Notification object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe Notification object.
 */
export const createMockNotification = (overrides: Partial<Notification> = {}): Notification => {
  const defaultNotification: Notification = {
    notification_id: getNextId(),
    user_id: `user-${getNextId()}`,
    content: 'This is a mock notification.',
    link_url: null,
    is_read: false,
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
  };

  return { ...defaultNotification, ...overrides };
};

/**
 * Creates a mock ProcessingStage object for use in tests.
 * @param overrides - An object containing properties to override the default mock values.
 * @returns A complete and type-safe ProcessingStage object.
 */
export const createMockProcessingStage = (
  overrides: Partial<ProcessingStage> = {},
): ProcessingStage => {
  const defaultStage: ProcessingStage = {
    name: 'Mock Stage',
    status: 'pending',
    detail: '',
    critical: true,
  };

  return { ...defaultStage, ...overrides };
};

export const createMockAppliance = (overrides: Partial<Appliance> = {}): Appliance => {
  return {
    appliance_id: 1,
    name: 'Oven',
    created_at: new Date().toISOString(),
    updated_at: new Date().toISOString(),
    ...overrides,
  };
};

// src/tests/utils/mockFactories.ts

// ... existing factories

export const createMockShoppingListItemPayload = (
  overrides: Partial<{ masterItemId: number; customItemName: string }> = {},
): { masterItemId?: number; customItemName?: string } => ({
  customItemName: 'Mock Item',
  ...overrides,
});

export const createMockRecipeCommentPayload = (
  overrides: Partial<{ content: string; parentCommentId: number }> = {},
): { content: string; parentCommentId?: number } => ({
  content: 'This is a mock comment.',
  ...overrides,
});

export const createMockProfileUpdatePayload = (
  overrides: Partial<Profile> = {},
): Partial<Profile> => ({
  full_name: 'Mock User',
  ...overrides,
});

export const createMockAddressPayload = (overrides: Partial<Address> = {}): Partial<Address> => ({
  address_line_1: '123 Mock St',
  city: 'Mockville',
  province_state: 'MS',
  postal_code: '12345',
  country: 'Mockland',
  ...overrides,
});

export const createMockSearchQueryPayload = (
  overrides: Partial<
    Omit<SearchQuery, 'search_query_id' | 'created_at' | 'updated_at' | 'user_id'>
  > = {},
): Omit<SearchQuery, 'search_query_id' | 'created_at' | 'updated_at' | 'user_id'> => ({
  query_text: 'mock search',
  result_count: 5,
  was_successful: true,
  ...overrides,
});

export const createMockWatchedItemPayload = (
  overrides: Partial<{ itemName: string; category: string }> = {},
): { itemName: string; category: string } => ({
  itemName: 'Mock Watched Item',
  category: 'Pantry',
  ...overrides,
});

export const createMockRegisterUserPayload = (
  overrides: Partial<{
    email: string;
    password: string;
    full_name: string;
    avatar_url: string | undefined;
  }> = {},
) => ({
  email: 'mock@example.com',
  password: 'password123',
  full_name: 'Mock User',
  avatar_url: undefined,
  ...overrides,
});

export const createMockLoginPayload = (
  overrides: Partial<{ email: string; password: string; rememberMe: boolean }> = {},
) => ({
  email: 'mock@example.com',
  password: 'password123',
  rememberMe: false,
  ...overrides,
});
