/**
 * Task dependencies schema — task-dependencies.
 * Postgres / Neon via Hyperdrive.
 *
 * Table:
 *  - task_dependencies: directed "blocks" edges between tasks
 *
 * All plain btree column indexes are declared here.
 * The UNIQUE constraint on (blocking_task_id, blocked_task_id) and
 * the self-reference CHECK are placed in the table callback.
 */
import {
  pgTable,
  uuid,
  timestamp,
  index,
  unique,
  check,
} from 'drizzle-orm/pg-core'
import { sql } from 'drizzle-orm'
import { tenants } from './tenants'
import { users } from './users'
import { tasks } from './tasks'

// ── task_dependencies ─────────────────────────────────────────────────────────

export const taskDependencies = pgTable(
  'task_dependencies',
  {
    id: uuid('id').primaryKey().defaultRandom(),
    tenantId: uuid('tenant_id')
      .notNull()
      .references(() => tenants.id, { onDelete: 'cascade' }),
    blockingTaskId: uuid('blocking_task_id')
      .notNull()
      .references(() => tasks.id, { onDelete: 'cascade' }),
    blockedTaskId: uuid('blocked_task_id')
      .notNull()
      .references(() => tasks.id, { onDelete: 'cascade' }),
    createdBy: uuid('created_by')
      .notNull()
      .references(() => users.id),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (t) => ({
    // Unique pair: prevents duplicate edges (same direction)
    blockingBlockedUniq: unique('task_dependencies_blocking_blocked_uniq').on(
      t.blockingTaskId,
      t.blockedTaskId,
    ),
    // Self-reference guard
    noSelfDepCheck: check(
      'task_dependencies_no_self_dep_check',
      sql`${t.blockingTaskId} <> ${t.blockedTaskId}`,
    ),
    // Bidirectional lookup indexes
    blockingTaskIdx: index('idx_td_blocking').on(t.blockingTaskId),
    blockedTaskIdx: index('idx_td_blocked').on(t.blockedTaskId),
    tenantIdx: index('idx_td_tenant').on(t.tenantId),
  }),
)

export type TaskDependencyRow = typeof taskDependencies.$inferSelect
export type NewTaskDependency = typeof taskDependencies.$inferInsert
