import { randomUUID } from "node:crypto";
import { index, integer, primaryKey, sqliteTable, text, uniqueIndex, } from "drizzle-orm/sqlite-core";
import { users } from "../../../core/db/schema.js";
const uuid = (name) => text(name).$defaultFn(() => randomUUID());
const nowFn = () => new Date();
/* ------------------------------------------------------------------ */
/* Familles                                                           */
/* ------------------------------------------------------------------ */
export const families = sqliteTable("families", {
    id: uuid("id").primaryKey(),
    name: text("name").notNull(),
    createdBy: text("created_by")
        .notNull()
        .references(() => users.id),
    /** Réglage famille : réactions activées/désactivées partout (posé par admin/coadmin). */
    reactionsEnabled: integer("reactions_enabled", { mode: "boolean" }).notNull().default(true),
    /** Réglage famille : commentaires activés/désactivés partout (posé par admin/coadmin). */
    commentsEnabled: integer("comments_enabled", { mode: "boolean" }).notNull().default(true),
    createdAt: integer("created_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
});
export const familyMembers = sqliteTable("family_members", {
    familyId: text("family_id")
        .notNull()
        .references(() => families.id, { onDelete: "cascade" }),
    userId: text("user_id")
        .notNull()
        .references(() => users.id, { onDelete: "cascade" }),
    role: text("role", { enum: ["admin", "coadmin", "viewer"] }).notNull().default("viewer"),
    /** Droits viewer : view (base) + options réactions/téléchargement
     *  (full = les deux) — ignoré pour admin/coadmin (toujours full). */
    permission: text("permission", { enum: ["full", "download", "reactions", "view"] })
        .notNull()
        .default("full"),
    /** Préférences de notification du membre. */
    notifyNewMedia: integer("notify_new_media", { mode: "boolean" }).notNull().default(true),
    notifyComments: integer("notify_comments", { mode: "boolean" }).notNull().default(true),
    joinedAt: integer("joined_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
}, (t) => [primaryKey({ columns: [t.familyId, t.userId] })]);
/* ------------------------------------------------------------------ */
/* Index des médias (pas d'octets — uniquement des métadonnées)        */
/* ------------------------------------------------------------------ */
export const media = sqliteTable("media", {
    id: uuid("id").primaryKey(),
    familyId: text("family_id")
        .notNull()
        .references(() => families.id, { onDelete: "cascade" }),
    /** Chemin relatif du fichier dans le stockage local de la famille. */
    path: text("path").notNull(),
    name: text("name").notNull(),
    caption: text("caption"),
    /** Empreinte sha256 du contenu — sert de etag local (dédup future). */
    etag: text("etag").notNull(),
    size: integer("size").notNull(),
    mime: text("mime").notNull(),
    capturedAt: integer("captured_at", { mode: "timestamp_ms" }).notNull(),
    capturedAtSource: text("captured_at_source", {
        enum: ["filename", "mtime", "exif", "client"],
    })
        .notNull()
        .default("mtime"),
    width: integer("width"),
    height: integer("height"),
    durationMs: integer("duration_ms"),
    hasPreview: integer("has_preview", { mode: "boolean" }).notNull().default(true),
    uploadedBy: text("uploaded_by").references(() => users.id),
    deletedAt: integer("deleted_at", { mode: "timestamp_ms" }),
    createdAt: integer("created_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
    updatedAt: integer("updated_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
}, (t) => [
    uniqueIndex("media_family_path_idx").on(t.familyId, t.path),
    index("media_family_captured_idx").on(t.familyId, t.capturedAt),
]);
/* ------------------------------------------------------------------ */
/* Albums                                                            */
/* ------------------------------------------------------------------ */
export const albums = sqliteTable("albums", {
    id: uuid("id").primaryKey(),
    familyId: text("family_id")
        .notNull()
        .references(() => families.id, { onDelete: "cascade" }),
    name: text("name").notNull(),
    coverMediaId: text("cover_media_id").references(() => media.id),
    createdAt: integer("created_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
});
export const albumMedia = sqliteTable("album_media", {
    albumId: text("album_id")
        .notNull()
        .references(() => albums.id, { onDelete: "cascade" }),
    mediaId: text("media_id")
        .notNull()
        .references(() => media.id, { onDelete: "cascade" }),
    addedAt: integer("added_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
}, (t) => [primaryKey({ columns: [t.albumId, t.mediaId] })]);
/* ------------------------------------------------------------------ */
/* Social                                                             */
/* ------------------------------------------------------------------ */
export const comments = sqliteTable("comments", {
    id: uuid("id").primaryKey(),
    familyId: text("family_id")
        .notNull()
        .references(() => families.id, { onDelete: "cascade" }),
    mediaId: text("media_id")
        .notNull()
        .references(() => media.id, { onDelete: "cascade" }),
    authorId: text("author_id")
        .notNull()
        .references(() => users.id),
    body: text("body").notNull(),
    createdAt: integer("created_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
    deletedAt: integer("deleted_at", { mode: "timestamp_ms" }),
}, (t) => [
    index("comments_media_idx").on(t.mediaId, t.createdAt),
    index("comments_family_idx").on(t.familyId),
]);
export const reactions = sqliteTable("reactions", {
    mediaId: text("media_id")
        .notNull()
        .references(() => media.id, { onDelete: "cascade" }),
    userId: text("user_id")
        .notNull()
        .references(() => users.id, { onDelete: "cascade" }),
    emoji: text("emoji").notNull(),
    createdAt: integer("created_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
}, (t) => [primaryKey({ columns: [t.mediaId, t.userId] })]);
export const mediaViews = sqliteTable("media_views", {
    mediaId: text("media_id")
        .notNull()
        .references(() => media.id, { onDelete: "cascade" }),
    userId: text("user_id")
        .notNull()
        .references(() => users.id, { onDelete: "cascade" }),
    firstViewedAt: integer("first_viewed_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
}, (t) => [primaryKey({ columns: [t.mediaId, t.userId] })]);
/* ------------------------------------------------------------------ */
/* Invitations                                                        */
/* ------------------------------------------------------------------ */
export const invitations = sqliteTable("invitations", {
    id: uuid("id").primaryKey(),
    familyId: text("family_id")
        .notNull()
        .references(() => families.id, { onDelete: "cascade" }),
    role: text("role", { enum: ["admin", "coadmin", "viewer"] }).notNull().default("viewer"),
    code: text("code").notNull().unique(),
    createdBy: text("created_by")
        .notNull()
        .references(() => users.id),
    expiresAt: integer("expires_at", { mode: "timestamp_ms" }).notNull(),
    maxUses: integer("max_uses").notNull().default(1),
    usedCount: integer("used_count").notNull().default(0),
    revokedAt: integer("revoked_at", { mode: "timestamp_ms" }),
    createdAt: integer("created_at", { mode: "timestamp_ms" })
        .notNull()
        .$defaultFn(nowFn),
});
//# sourceMappingURL=schema.js.map