import {
  pgTable,
  uuid,
  text,
  bigint,
  jsonb,
  index,
} from "drizzle-orm/pg-core";

// Epoch-millis timestamps (matches the client's number-based model exactly).
const ms = (name: string) => bigint(name, { mode: "number" });

export const users = pgTable("users", {
  id: uuid("id").primaryKey(),
  email: text("email").notNull().unique(),
  username: text("username").unique(),
  passwordHash: text("password_hash").notNull(),
  displayName: text("display_name").notNull(),
  avatarUrl: text("avatar_url"),
  createdAt: ms("created_at").notNull(),
  updatedAt: ms("updated_at").notNull(),
});

export const refreshTokens = pgTable("refresh_tokens", {
  id: uuid("id").primaryKey(),
  userId: uuid("user_id")
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),
  tokenHash: text("token_hash").notNull(),
  expiresAt: ms("expires_at").notNull(),
  revokedAt: ms("revoked_at"),
  createdAt: ms("created_at").notNull(),
});

export const locations = pgTable(
  "locations",
  {
    id: uuid("id").primaryKey(),
    ownerId: uuid("owner_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    name: text("name").notNull(),
    address: text("address"),
    createdAt: ms("created_at").notNull(),
    updatedAt: ms("updated_at").notNull(),
    deletedAt: ms("deleted_at"),
  },
  (t) => ({
    ownerUpdatedIdx: index("locations_owner_updated_idx").on(
      t.ownerId,
      t.updatedAt,
    ),
  }),
);

export const players = pgTable(
  "players",
  {
    id: uuid("id").primaryKey(),
    ownerId: uuid("owner_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    name: text("name").notNull(),
    avatar: text("avatar"),
    createdAt: ms("created_at").notNull(),
    updatedAt: ms("updated_at").notNull(),
    deletedAt: ms("deleted_at"),
  },
  (t) => ({
    ownerUpdatedIdx: index("players_owner_updated_idx").on(
      t.ownerId,
      t.updatedAt,
    ),
  }),
);

export const friendships = pgTable(
  "friendships",
  {
    id: uuid("id").primaryKey(),
    requesterId: uuid("requester_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    addresseeId: uuid("addressee_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    // "pending" | "accepted" | "blocked"
    status: text("status").notNull(),
    createdAt: ms("created_at").notNull(),
    updatedAt: ms("updated_at").notNull(),
  },
  (t) => ({
    requesterIdx: index("friendships_requester_idx").on(t.requesterId),
    addresseeIdx: index("friendships_addressee_idx").on(t.addresseeId),
  }),
);

export const sessions = pgTable(
  "sessions",
  {
    id: uuid("id").primaryKey(),
    ownerId: uuid("owner_id")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    gameId: text("game_id").notNull(),
    dateStart: ms("date_start").notNull(),
    dateEnd: ms("date_end"),
    players: jsonb("players").notNull(),
    rounds: jsonb("rounds").notNull(),
    status: text("status").notNull(),
    options: jsonb("options").notNull(),
    winnerIds: jsonb("winner_ids"),
    locationId: uuid("location_id"),
    createdAt: ms("created_at").notNull(),
    updatedAt: ms("updated_at").notNull(),
    deletedAt: ms("deleted_at"),
  },
  (t) => ({
    ownerUpdatedIdx: index("sessions_owner_updated_idx").on(
      t.ownerId,
      t.updatedAt,
    ),
  }),
);
