import type { AdapterAccount } from "@auth/core/adapters";
import { relations } from "drizzle-orm";
import {
  boolean,
  integer,
  pgTable,
  primaryKey,
  serial,
  smallint,
  text,
  timestamp,
  varchar,
} from "drizzle-orm/pg-core";

export const users = pgTable("user", {
  id: text("id").notNull().primaryKey(),
  name: text("name"),
  email: text("email").notNull(),
  emailVerified: timestamp("emailVerified", { mode: "date" }),
  image: text("image"),
});

export const accounts = pgTable(
  "account",
  {
    userId: text("userId")
      .notNull()
      .references(() => users.id, { onDelete: "cascade" }),
    type: text("type").$type<AdapterAccount["type"]>().notNull(),
    provider: text("provider").notNull(),
    providerAccountId: text("providerAccountId").notNull(),
    refresh_token: text("refresh_token"),
    access_token: text("access_token"),
    expires_at: integer("expires_at"),
    token_type: text("token_type"),
    scope: text("scope"),
    id_token: text("id_token"),
    session_state: text("session_state"),
  },
  (account) => ({
    compoundKey: primaryKey({
      columns: [account.provider, account.providerAccountId],
    }),
  }),
);

export const sessions = pgTable("session", {
  sessionToken: text("sessionToken").notNull().primaryKey(),
  userId: text("userId")
    .notNull()
    .references(() => users.id, { onDelete: "cascade" }),
  expires: timestamp("expires", { mode: "date" }).notNull(),
});

export const verificationTokens = pgTable(
  "verificationToken",
  {
    identifier: text("identifier").notNull(),
    token: text("token").notNull(),
    expires: timestamp("expires", { mode: "date" }).notNull(),
  },
  (vt) => ({
    compoundKey: primaryKey({ columns: [vt.identifier, vt.token] }),
  }),
);

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

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

export const guilds = pgTable("guild", {
  id: varchar("id", { length: 20 }).primaryKey(),
  timezone: text("timezone").notNull(),
});

export const guildsRelations = relations(guilds, ({ one, many }) => ({
  matches: many(matchPlannings),
  timePlanning: one(timePlannings, {
    fields: [guilds.id],
    references: [timePlannings.guildId],
  }),
}));

export const timePlannings = pgTable("time_planning", {
  id: serial("id").primaryKey(),
  guildId: varchar("guild_id", { length: 20 })
    .notNull()
    .unique()
    .references(() => guilds.id, {
      onDelete: "cascade",
    }),
  channelId: varchar("channel_id", { length: 20 }).notNull(),
  target_interval: smallint("target_interval").notNull(),
  roles: boolean("roles").notNull(),
  isAvailableRoleId: varchar("is_available_role_id", { length: 20 }),
  wantsToBeNotifieRoledId: varchar("wants_to_be_notified_role_id", {
    length: 20,
  }),
});

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

export const tpMessages = pgTable("tp_message", {
  messageId: varchar("message_id", { length: 20 }).primaryKey(),
  day: smallint("day").notNull(),
  planId: integer("plan_id")
    .notNull()
    .references(() => timePlannings.id, { onDelete: "cascade" }),
});

export const tpMessagesRelations = relations(tpMessages, ({ one }) => ({
  plan: one(timePlannings, {
    fields: [tpMessages.planId],
    references: [timePlannings.id],
  }),
}));
