import {
  pgTable,
  uuid,
  text,
  boolean,
  timestamp,
  integer,
} from "drizzle-orm/pg-core";

export const users = pgTable("users", {
  id: uuid("id").primaryKey().defaultRandom(),
  displayName: text("display_name").notNull(),
  email: text("email").notNull().unique(),
  isAdmin: boolean("is_admin").notNull().default(false),
  watchingNowTvSlots: integer("watching_now_tv_slots").notNull().default(5),
  watchingNowMovieSlots: integer("watching_now_movie_slots").notNull().default(10),
  createdAt: timestamp("created_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// A linked Plex account.
//
// Linking does two things at once, which is why it is worth a table of its own
// rather than another row in user_identities: it grants the person access to
// the Plex libraries, and it makes their Plex watchlist readable as demand.
// Neither is possible without knowing which Plex account belongs to which user.
//
// NO TOKEN IS STORED. The link is proved by the PIN flow -- the user signs in
// at plex.tv, we exchange the PIN for a token, ask Plex who it belongs to, and
// then throw the token away. Reading their watchlist needs the OWNER's token
// and the account uuid, both of which we already have, so keeping a second
// person's credential would buy nothing and be one more thing to leak.
export const plexAccounts = pgTable("plex_accounts", {
  id: uuid("id").primaryKey().defaultRandom(),
  userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }).unique(),
  // Plex's numeric account id, and the uuid the community API keys watchlists on.
  plexUserId: text("plex_user_id").notNull().unique(),
  plexUuid: text("plex_uuid"),
  plexUsername: text("plex_username").notNull(),
  plexEmail: text("plex_email"),
  // When the libraries were shared, and which ones. Recorded so a failed or
  // partial share is visible rather than being assumed to have worked.
  librariesSharedAt: timestamp("libraries_shared_at"),
  sharedSectionIds: text("shared_section_ids").array(),
  linkedAt: timestamp("linked_at").notNull().defaultNow(),
  updatedAt: timestamp("updated_at").notNull().defaultNow(),
});

// Maps Authentik (or other OIDC) external identities to local users.
export const userIdentities = pgTable("user_identities", {
  id: uuid("id").primaryKey().defaultRandom(),
  userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
  provider: text("provider").notNull(),   // e.g. "authentik"
  externalId: text("external_id").notNull(), // sub claim from OIDC
  createdAt: timestamp("created_at").notNull().defaultNow(),
});
