/**
 * Query layer for the onboarding flow — owns reads/writes that mark a user as
 * onboarded and update their profile fields. Higher layers (API routes) never
 * touch Drizzle directly for these columns.
 */

import { and, eq, isNull, sql } from 'drizzle-orm';
import type { DrizzleClient } from '../client.js';
import { users } from '../schema.js';
import type { OnboardingBody } from '../../schemas/onboarding.js';

export interface CompleteOnboardingResult {
  changed: boolean;
}

/**
 * Marks onboarding complete for `userId` AND updates any provided profile
 * fields in one UPDATE. Idempotent: a second call for an already-completed
 * user returns `{ changed: false }` and does NOT overwrite stored fields.
 *
 * Note: pushOptIn lives on preferencesProfile JSONB. Use `setPushOptIn`
 * separately to avoid clobbering other JSONB keys.
 */
export async function completeOnboarding(
  db: DrizzleClient,
  userId: string,
  body: OnboardingBody,
): Promise<CompleteOnboardingResult> {
  const updateSet: Partial<typeof users.$inferInsert> = {
    onboardingCompletedAt: new Date(),
  };
  if (body.displayName !== undefined) updateSet.displayName = body.displayName;
  if (body.city !== undefined) updateSet.city = body.city;
  if (body.cityCode !== undefined) updateSet.cityCode = body.cityCode;
  if (body.birthMonth !== undefined) updateSet.birthMonth = body.birthMonth;
  if (body.birthDay !== undefined) updateSet.birthDay = body.birthDay;

  const result = await db
    .update(users)
    .set(updateSet)
    .where(and(eq(users.id, userId), isNull(users.onboardingCompletedAt)))
    .returning({ id: users.id });

  return { changed: result.length > 0 };
}

/**
 * Updates `users.preferencesProfile.pushOptIn` without touching other JSONB
 * fields. Uses jsonb_set so concurrent writers to other keys don't lose data.
 */
export async function setPushOptIn(
  db: DrizzleClient,
  userId: string,
  pushOptIn: boolean,
): Promise<void> {
  await db.execute(sql`
    UPDATE users
    SET preferences_profile = jsonb_set(
      COALESCE(preferences_profile, '{}'::jsonb),
      '{pushOptIn}',
      to_jsonb(${pushOptIn}::boolean),
      true
    )
    WHERE id = ${userId}
  `);
}
