import {
  pgTable,
  uuid,
  varchar,
  text,
  integer,
  jsonb,
  timestamp,
  index,
  uniqueIndex,
  check,
} from 'drizzle-orm/pg-core';
import { sql } from 'drizzle-orm';
import { projects } from './projects';
import { generations } from './generations';
import { images } from './images';

export const promptUrlCache = pgTable(
  'prompt_url_cache',
  {
    id: uuid('id').primaryKey().defaultRandom(),

    // Relations
    projectId: uuid('project_id')
      .notNull()
      .references(() => projects.id, { onDelete: 'cascade' }),
    generationId: uuid('generation_id')
      .notNull()
      .references(() => generations.id, { onDelete: 'cascade' }),
    imageId: uuid('image_id')
      .notNull()
      .references(() => images.id, { onDelete: 'cascade' }),

    // Cache keys (SHA-256 hashes)
    promptHash: varchar('prompt_hash', { length: 64 }).notNull(),
    queryParamsHash: varchar('query_params_hash', { length: 64 }).notNull(),

    // Original request (for debugging/reconstruction)
    originalPrompt: text('original_prompt').notNull(),
    requestParams: jsonb('request_params').$type<Record<string, unknown>>().notNull(),

    // Cache statistics
    hitCount: integer('hit_count').notNull().default(0),
    lastHitAt: timestamp('last_hit_at'),

    // Audit
    createdAt: timestamp('created_at').notNull().defaultNow(),
  },
  (table) => ({
    // CHECK constraints
    hitCountCheck: check('hit_count_check', sql`${table.hitCount} >= 0`),

    // Indexes
    // Unique composite index for cache lookup
    cacheKeyIdx: uniqueIndex('idx_cache_key').on(
      table.projectId,
      table.promptHash,
      table.queryParamsHash,
    ),

    // Index for generation lookup
    generationIdx: index('idx_cache_generation').on(table.generationId),

    // Index for image lookup
    imageIdx: index('idx_cache_image').on(table.imageId),

    // Index for cache hit analytics
    hitsIdx: index('idx_cache_hits').on(
      table.projectId,
      table.hitCount.desc(),
      table.createdAt.desc(),
    ),
  }),
);

export type PromptUrlCache = typeof promptUrlCache.$inferSelect;
export type NewPromptUrlCache = typeof promptUrlCache.$inferInsert;
