import { relations } from "drizzle-orm";
import {
  bigint,
  boolean,
  pgTable,
  primaryKey,
  serial,
  smallint,
  text,
  timestamp,
  varchar,
} from "drizzle-orm/pg-core";

export const cache = pgTable("cache", {
  key: varchar("key").primaryKey(),
  value: varchar("value").notNull(),
  createdAt: timestamp("created_at").notNull(),
});

export const users = pgTable("user", {
  id: varchar("id", { length: 24 }).primaryKey(),
  discord_id: text("discord_id").notNull(),
  name: text("name"),
  image: text("image"),
});

export const sessions = pgTable("session", {
  id: varchar("id", { length: 24 }).primaryKey(),
  userId: varchar("user_id", { length: 24 })
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),
  expiresAt: timestamp("expires_at", {
    withTimezone: true,
    mode: "date",
  }).notNull(),
});

export const discordTokens = pgTable("tokens", {
  userId: varchar("user_id", { length: 24 })
    .primaryKey()
    .references(() => users.id, { onDelete: "cascade" }),
  refreshToken: text("refresh_token").notNull(),
  accessToken: text("access_token").notNull(),
  expiresAt: timestamp("expires_at", { mode: "date" }).notNull(),
});

export const guilds = pgTable("guilds", {
  id: bigint("id", { mode: "bigint" }).primaryKey(),
  timezone: text("timezone").notNull().default("Etc/UTC"),
  tpChannelId: bigint("tp_channel_id", { mode: "bigint" }),
  tpInterval: smallint("target_interval").notNull().default(64),
  tpRolesEnabled: boolean("tp_roles_enabled").notNull().default(false),
  isAvailableRoleId: bigint("is_available_role_id", { mode: "bigint" }),
  wantsToBeNotifieRoledId: bigint("wants_to_be_notified_role_id", {
    mode: "bigint",
  }),
});

export const guildsRelations = relations(guilds, ({ many }) => ({
  tpMessages: many(tpMessages),
  matches: many(matches),
}));

export const tpMessages = pgTable(
  "tp_messages",
  {
    messageId: bigint("message_id", { mode: "bigint" }),
    day: smallint("day").notNull(),
    guildId: bigint("guild_id", { mode: "bigint" })
      .notNull()
      .references(() => guilds.id, { onDelete: "cascade" }),
  },
  (table) => {
    return {
      pk: primaryKey({ columns: [table.guildId, table.day] }),
    };
  },
);

export const tpMessagesRelations = relations(tpMessages, ({ one }) => ({
  guild: one(guilds, {
    fields: [tpMessages.guildId],
    references: [guilds.id],
  }),
}));

export const matches = pgTable("matches", {
  id: serial("id").primaryKey(),
  channelId: bigint("channel_id", { mode: "bigint" }).notNull(),
  matchType: varchar("match_type", { length: 50 }).notNull(),
  createrId: bigint("creater_id", { mode: "bigint" }).notNull(),
  roleId: bigint("role_id", { mode: "bigint" }).notNull(),
  opponentName: varchar("opponent_name", { length: 100 }).notNull(),
  messageId: bigint("message_id", { mode: "bigint" }).notNull(),
  utc_ts: timestamp("utc_ts").notNull(),
  guildId: bigint("guild_id", { mode: "bigint" })
    .notNull()
    .references(() => guilds.id, { onDelete: "cascade" }),
});

export const matchPlanningsRelations = relations(matches, ({ one }) => ({
  guild: one(guilds, {
    fields: [matches.guildId],
    references: [guilds.id],
  }),
}));
