import { pgTable, serial, integer, text, timestamp, jsonb, check, uniqueIndex, foreignKey } from 'drizzle-orm/pg-core';
import { users } from '../auth/schema';
import { sql } from 'drizzle-orm';
import { serverIntegrations } from '../server/schema';

export const userSettings = pgTable('user_settings', {
  userId: integer('user_id')
    .primaryKey()
    .references(() => users.id, { onDelete: 'cascade' }),
  settings: jsonb('settings').notNull().default({}),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
});

export const userState = pgTable('user_state', {
  userId: integer('user_id')
    .primaryKey()
    .references(() => users.id, { onDelete: 'cascade' }),
  state: jsonb('state').notNull().default({}),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
});

// Per-user integrations the code knows how to read. Same reasoning as SERVER_PROVIDERS in ./server.
const USER_PROVIDERS = ['google', 'browser-relay'] as const;

export const userIntegrations = pgTable(
  'user_integrations',
  {
    id: serial('id').primaryKey(),
    userId: integer('user_id')
      .notNull()
      .references(() => users.id, { onDelete: 'cascade' }),
    provider: text('provider').notNull(),
    // Named explicitly. Drizzle's generated name would be
    // `user_integrations_server_integration_id_server_integrations_id_fk` — 65 characters, and Postgres
    // truncates identifiers at 63. It stores the truncated form, drizzle keeps comparing against its
    // own 65-char version, and every `db:push` drops and re-adds the constraint forever.
    serverIntegrationId: integer('server_integration_id'),
    config: jsonb('config').notNull().default({}),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
    updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (table) => [
    foreignKey({
      name: 'fk_user_integrations_server_integration',
      columns: [table.serverIntegrationId],
      foreignColumns: [serverIntegrations.id],
    }).onDelete('set null'),
    uniqueIndex('uq_user_integrations_user_provider').on(table.userId, table.provider),
    check(
      'ck_user_integrations_provider',
      // sql.raw — see the note on ck_server_integrations_provider; an interpolated JS string becomes a
      // bound `$1` that Postgres will not accept in a CHECK.
      sql`${table.provider} IN (${sql.join(
        USER_PROVIDERS.map((p) => sql.raw(`'${p}'`)),
        sql`, `,
      )})`,
    ),
  ],
);

export const dockConfigs = pgTable('dock_configs', {
  userId: integer('user_id')
    .primaryKey()
    .references(() => users.id, { onDelete: 'cascade' }),
  paths: jsonb('paths').notNull().default([]),
  updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
});
