import { bigint, boolean, integer, pgEnum, pgTable, text, timestamp, uniqueIndex } from "drizzle-orm/pg-core";
import { intId, intPk } from "./columns";
import { users, workspaces } from "./identity";

export const channelTypeEnum = pgEnum("channel_type", ["public", "private", "dm", "group_dm"]);

export const channels = pgTable("channels", {
  id: intPk(),
  workspaceId: intId("workspace_id")
    .notNull()
    .references(() => workspaces.id),
  type: channelTypeEnum("type").notNull(),
  name: text("name"),
  topic: text("topic"),
  purpose: text("purpose"),
  createdBy: intId("created_by")
    .notNull()
    .references(() => users.id),
  isArchived: boolean("is_archived").notNull().default(false),
  lastMessageAt: timestamp("last_message_at", { withTimezone: true }),
  memberCount: integer("member_count").notNull().default(0),
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
});

// Per-channel monotonic counter (ADR-001) — never a global sequence.
export const channelSeq = pgTable("channel_seq", {
  channelId: intId("channel_id")
    .primaryKey()
    .references(() => channels.id),
  lastSeq: bigint("last_seq", { mode: "number" }).notNull().default(0),
});

export const channelMembers = pgTable(
  "channel_members",
  {
    channelId: intId("channel_id")
      .notNull()
      .references(() => channels.id),
    userId: intId("user_id")
      .notNull()
      .references(() => users.id),
    role: text("role").notNull().default("member"),
    joinedAt: timestamp("joined_at", { withTimezone: true }).notNull().defaultNow(),
    lastReadSeq: bigint("last_read_seq", { mode: "number" }).notNull().default(0),
    lastReadAt: timestamp("last_read_at", { withTimezone: true }),
    mentionCount: integer("mention_count").notNull().default(0),
    notifPref: text("notif_pref").notNull().default("all"),
    isMuted: boolean("is_muted").notNull().default(false),
    isStarred: boolean("is_starred").notNull().default(false),
    // Closing a DM is personal: it hides the conversation for this member
    // without removing history or affecting the other participants.
    isClosed: boolean("is_closed").notNull().default(false),
    sectionId: text("section_id"),
  },
  (t) => [uniqueIndex("channel_members_pk").on(t.channelId, t.userId)],
);

/**
 * Apps linked into a room (the About panel's "Integrations" strip). One row
 * per (channel, provider): a room links a given provider once, and re-linking
 * it updates the label/url rather than stacking duplicates.
 */
export const channelIntegrations = pgTable(
  "channel_integrations",
  {
    id: intPk(),
    channelId: intId("channel_id")
      .notNull()
      .references(() => channels.id),
    provider: text("provider").notNull(),
    label: text("label"),
    externalUrl: text("external_url"),
    addedBy: intId("added_by")
      .notNull()
      .references(() => users.id),
    addedAt: timestamp("added_at", { withTimezone: true }).notNull().defaultNow(),
  },
  (t) => [uniqueIndex("channel_integrations_channel_provider_idx").on(t.channelId, t.provider)],
);
