import { index, jsonb, pgTable, text, timestamp, uniqueIndex } from 'drizzle-orm/pg-core';
import { sql } from 'drizzle-orm';

import { ports } from './ports';

/**
 * Saved report templates. Each row captures a named, port-scoped
 * configuration that backs the "Saved templates" dropdown in the
 * Export-as-PDF dialog. The `config` JSONB matches the discriminated-
 * union shape the route schema enforces, so reusing a template is a
 * straight pass-through to /api/v1/reports/generate.
 *
 * Migration: 0079_report_templates.sql.
 */
export const reportTemplates = pgTable(
  'report_templates',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    portId: text('port_id')
      .notNull()
      .references(() => ports.id, { onDelete: 'cascade' }),
    /** Mirrors the discriminator on ReportConfig — 'dashboard' |
     *  'clients' | 'berths' | 'interests'. Validated at the route
     *  layer. */
    kind: text('kind').notNull(),
    name: text('name').notNull(),
    description: text('description'),
    /** Untyped at the Drizzle layer; route + service layers validate
     *  via the same zod schemas they use on `/api/v1/reports/generate`. */
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    config: jsonb('config').$type<Record<string, any>>().notNull(),
    createdBy: text('created_by').notNull(),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
    updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (table) => [
    index('idx_report_templates_port').on(table.portId),
    index('idx_report_templates_port_kind').on(table.portId, table.kind),
    // Sibling-name uniqueness per port+kind. The lower() expression in
    // the SQL migration mirrors how case-insensitive collisions are
    // handled elsewhere in the schema.
    uniqueIndex('uniq_report_templates_port_kind_name').on(
      table.portId,
      table.kind,
      sql`LOWER(${table.name})`,
    ),
  ],
);

export type ReportTemplate = typeof reportTemplates.$inferSelect;
export type NewReportTemplate = typeof reportTemplates.$inferInsert;
