import { boolean, pgTable, text, timestamp } from 'drizzle-orm/pg-core'

export const oauthClients = pgTable('oauth_clients', {
  id: text('id').primaryKey(),
  name: text('name').notNull(),
  redirectUris: text('redirect_uris').notNull(),
  scopes: text('scopes').notNull(),
  confidential: boolean('confidential').notNull().default(false),
  clientSecretHash: text('client_secret_hash'),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull(),
})

export const oauthCodes = pgTable('oauth_codes', {
  id: text('id').primaryKey(),
  clientId: text('client_id')
    .notNull()
    .references(() => oauthClients.id),
  redirectUri: text('redirect_uri').notNull(),
  scope: text('scope').notNull(),
  codeChallenge: text('code_challenge').notNull(),
  codeChallengeMethod: text('code_challenge_method').notNull(),
  codeHash: text('code_hash').notNull().unique(),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull(),
  expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
  usedAt: timestamp('used_at', { withTimezone: true }),
})

export const oauthTokens = pgTable('oauth_tokens', {
  id: text('id').primaryKey(),
  clientId: text('client_id')
    .notNull()
    .references(() => oauthClients.id),
  codeId: text('code_id')
    .notNull()
    .references(() => oauthCodes.id),
  accessTokenPrefix: text('access_token_prefix').notNull().unique(),
  accessTokenHash: text('access_token_hash').notNull().unique(),
  scope: text('scope').notNull(),
  tokenType: text('token_type').notNull(),
  createdAt: timestamp('created_at', { withTimezone: true }).notNull(),
  expiresAt: timestamp('expires_at', { withTimezone: true }).notNull(),
})

export const oauthProviderCreationSql = () =>
  `CREATE TABLE IF NOT EXISTS oauth_clients (
    id text PRIMARY KEY,
    name text NOT NULL,
    redirect_uris text NOT NULL,
    scopes text NOT NULL,
    confidential boolean NOT NULL DEFAULT false,
    client_secret_hash text,
    created_at timestamptz NOT NULL
  );
  CREATE TABLE IF NOT EXISTS oauth_codes (
    id text PRIMARY KEY,
    client_id text NOT NULL REFERENCES oauth_clients(id),
    redirect_uri text NOT NULL,
    scope text NOT NULL,
    code_challenge text NOT NULL,
    code_challenge_method text NOT NULL,
    code_hash text NOT NULL UNIQUE,
    created_at timestamptz NOT NULL,
    expires_at timestamptz NOT NULL,
    used_at timestamptz
  );
  CREATE TABLE IF NOT EXISTS oauth_tokens (
    id text PRIMARY KEY,
    client_id text NOT NULL REFERENCES oauth_clients(id),
    code_id text NOT NULL REFERENCES oauth_codes(id),
    access_token_prefix text NOT NULL UNIQUE,
    access_token_hash text NOT NULL UNIQUE,
    scope text NOT NULL,
    token_type text NOT NULL,
    created_at timestamptz NOT NULL,
    expires_at timestamptz NOT NULL
  )`

export const oauthProviderSchema = {
  oauthClients,
  oauthCodes,
  oauthTokens,
}

export type OAuthProviderSchema = typeof oauthProviderSchema
