/**
 * AuditLog Entity
 * Registro de auditoría para trazabilidad de operaciones
 *
 * @module Admin
 * @table admin.audit_logs
 */

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  CreateDateColumn,
  ManyToOne,
  JoinColumn,
  Index,
} from 'typeorm';
import { Tenant } from '../../core/entities/tenant.entity';
import { User } from '../../core/entities/user.entity';

export type AuditCategory =
  | 'authentication'
  | 'user_management'
  | 'critical_operation'
  | 'administration'
  | 'data_access'
  | 'system';

export type AuditAction =
  | 'login'
  | 'logout'
  | 'login_failed'
  | 'password_change'
  | 'password_reset'
  | 'create'
  | 'read'
  | 'update'
  | 'delete'
  | 'approve'
  | 'reject'
  | 'export'
  | 'import'
  | 'configure'
  | 'backup'
  | 'restore';

export type AuditSeverity = 'low' | 'medium' | 'high' | 'critical';

@Entity({ schema: 'admin', name: 'audit_logs' })
@Index(['tenantId'])
@Index(['userId'])
@Index(['category'])
@Index(['action'])
@Index(['entityType', 'entityId'])
@Index(['createdAt'])
@Index(['severity'])
@Index(['ipAddress'])
export class AuditLog {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ name: 'tenant_id', type: 'uuid' })
  tenantId: string;

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

  @Column({
    type: 'varchar',
    length: 30,
  })
  category: AuditCategory;

  @Column({
    type: 'varchar',
    length: 30,
  })
  action: AuditAction;

  @Column({
    type: 'varchar',
    length: 20,
    default: 'medium',
  })
  severity: AuditSeverity;

  @Column({
    name: 'entity_type',
    type: 'varchar',
    length: 100,
    nullable: true,
    comment: 'Type of entity affected (e.g., User, Estimacion)',
  })
  entityType: string | null;

  @Column({
    name: 'entity_id',
    type: 'uuid',
    nullable: true,
    comment: 'ID of the affected entity',
  })
  entityId: string | null;

  @Column({
    name: 'entity_name',
    type: 'varchar',
    length: 200,
    nullable: true,
    comment: 'Human-readable name of the entity',
  })
  entityName: string | null;

  @Column({
    type: 'text',
    comment: 'Human-readable description of the action',
  })
  description: string;

  @Column({
    name: 'old_values',
    type: 'jsonb',
    nullable: true,
    comment: 'Previous values before the change',
  })
  oldValues: Record<string, any> | null;

  @Column({
    name: 'new_values',
    type: 'jsonb',
    nullable: true,
    comment: 'New values after the change',
  })
  newValues: Record<string, any> | null;

  @Column({
    name: 'changed_fields',
    type: 'varchar',
    array: true,
    nullable: true,
    comment: 'List of fields that were changed',
  })
  changedFields: string[] | null;

  @Column({
    name: 'ip_address',
    type: 'varchar',
    length: 45,
    nullable: true,
  })
  ipAddress: string | null;

  @Column({
    name: 'user_agent',
    type: 'varchar',
    length: 500,
    nullable: true,
  })
  userAgent: string | null;

  @Column({
    name: 'request_id',
    type: 'varchar',
    length: 100,
    nullable: true,
    comment: 'Request/correlation ID for tracing',
  })
  requestId: string | null;

  @Column({
    name: 'session_id',
    type: 'varchar',
    length: 100,
    nullable: true,
  })
  sessionId: string | null;

  @Column({
    type: 'varchar',
    length: 100,
    nullable: true,
    comment: 'Module where action occurred',
  })
  module: string | null;

  @Column({
    type: 'varchar',
    length: 200,
    nullable: true,
    comment: 'API endpoint or route',
  })
  endpoint: string | null;

  @Column({
    name: 'http_method',
    type: 'varchar',
    length: 10,
    nullable: true,
  })
  httpMethod: string | null;

  @Column({
    name: 'response_status',
    type: 'integer',
    nullable: true,
  })
  responseStatus: number | null;

  @Column({
    name: 'duration_ms',
    type: 'integer',
    nullable: true,
    comment: 'Request duration in milliseconds',
  })
  durationMs: number | null;

  @Column({
    name: 'is_success',
    type: 'boolean',
    default: true,
  })
  isSuccess: boolean;

  @Column({
    name: 'error_message',
    type: 'text',
    nullable: true,
  })
  errorMessage: string | null;

  @Column({
    type: 'jsonb',
    nullable: true,
    comment: 'Additional context data',
  })
  metadata: Record<string, any> | null;

  @Column({
    name: 'retention_days',
    type: 'integer',
    default: 90,
    comment: 'Days to retain this log (90 for operational, 1825 for critical)',
  })
  retentionDays: number;

  @CreateDateColumn({ name: 'created_at', type: 'timestamptz' })
  createdAt: Date;

  // Relations
  @ManyToOne(() => Tenant)
  @JoinColumn({ name: 'tenant_id' })
  tenant: Tenant;

  @ManyToOne(() => User)
  @JoinColumn({ name: 'user_id' })
  user: User | null;
}
