/**
 * ChangeLog Entity
 *
 * Registro automático de cambios a nivel de base de datos
 * mediante triggers. Captura INSERT, UPDATE, DELETE en tablas críticas.
 *
 * @module Admin
 * @table audit.change_log
 * @gap GAP-007
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  Index,
} from 'typeorm';

export type OperationType = 'INSERT' | 'UPDATE' | 'DELETE' | 'TRUNCATE';

@Entity({ schema: 'audit', name: 'change_log' })
@Index(['tenantId'])
@Index(['userId'])
@Index(['tableSchema', 'tableName'])
@Index(['recordId'])
@Index(['executedAt'])
@Index(['executedDate'])
@Index(['operation'])
export class ChangeLog {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  // Contexto
  @Column({ name: 'tenant_id', type: 'uuid', nullable: true })
  tenantId?: string;

  @Column({ name: 'user_id', type: 'uuid', nullable: true })
  userId?: string;

  @Column({ name: 'session_id', length: 100, nullable: true })
  sessionId?: string;

  // Operación
  @Column({ type: 'varchar', length: 10 })
  operation!: OperationType;

  @Column({ name: 'table_schema', length: 63 })
  tableSchema!: string;

  @Column({ name: 'table_name', length: 63 })
  tableName!: string;

  @Column({ name: 'record_id', type: 'uuid', nullable: true })
  recordId?: string;

  // Datos
  @Column({ name: 'old_data', type: 'jsonb', nullable: true })
  oldData?: Record<string, any>;

  @Column({ name: 'new_data', type: 'jsonb', nullable: true })
  newData?: Record<string, any>;

  @Column({ name: 'changed_fields', type: 'text', array: true, nullable: true })
  changedFields?: string[];

  // Metadatos
  @Column({ name: 'client_ip', type: 'inet', nullable: true })
  clientIp?: string;

  @Column({ name: 'user_agent', type: 'text', nullable: true })
  userAgent?: string;

  @Column({ name: 'application_name', length: 100, nullable: true })
  applicationName?: string;

  // Timestamp
  @Column({ name: 'executed_at', type: 'timestamptz', default: () => 'NOW()' })
  executedAt!: Date;

  // Campo generado (solo lectura)
  @Column({ name: 'executed_date', type: 'date', insert: false, update: false })
  executedDate?: Date;
}
