import { and, eq } from "drizzle-orm";
import { createId } from "@paralleldrive/cuid2";
import { getDb } from "../config/database.js";
import {
  notificationPreferences,
  type NotificationPreference,
  type NewNotificationPreference,
} from "../notifications/notifications.schema.js";

/**
 * PreferencesRepository —— 用户偏好数据访问层。
 */

export async function findByUserId(
  userId: string,
): Promise<NotificationPreference[]> {
  const db = getDb();
  return db
    .select()
    .from(notificationPreferences)
    .where(eq(notificationPreferences.userId, userId));
}

export async function findByUserIdAndType(
  userId: string,
  type: string,
): Promise<NotificationPreference | undefined> {
  const db = getDb();
  const [row] = await db
    .select()
    .from(notificationPreferences)
    .where(
      and(
        eq(notificationPreferences.userId, userId),
        eq(
          notificationPreferences.type,
          type as NotificationPreference["type"],
        ),
      ),
    )
    .limit(1);
  return row;
}

export async function upsert(
  userId: string,
  row: Omit<
    NewNotificationPreference,
    "id" | "userId" | "createdAt" | "updatedAt"
  >,
): Promise<NotificationPreference> {
  const db = getDb();
  const existing = await findByUserIdAndType(userId, row.type as string);

  if (existing) {
    await db
      .update(notificationPreferences)
      .set({
        channels: row.channels,
        frequencyLimit: row.frequencyLimit,
        quietHoursStart: row.quietHoursStart,
        quietHoursEnd: row.quietHoursEnd,
        quietHoursTimezone: row.quietHoursTimezone,
        enabled: row.enabled,
      })
      .where(eq(notificationPreferences.id, existing.id));
    return { ...existing, ...row } as NotificationPreference;
  }

  const newPref: NewNotificationPreference = {
    id: createId(),
    userId,
    ...row,
  };
  await db.insert(notificationPreferences).values(newPref);
  return newPref as NotificationPreference;
}

export async function deleteByUserId(userId: string): Promise<void> {
  const db = getDb();
  await db
    .delete(notificationPreferences)
    .where(eq(notificationPreferences.userId, userId));
}
