import {
  Entity,
  Column,
  PrimaryColumn,
  CreateDateColumn,
  ManyToOne,
  JoinColumn,
  BeforeInsert,
} from 'typeorm';
import { User } from './user.entity';

export enum AuditAction {
  CREATE = 'CREATE',
  READ = 'READ',
  UPDATE = 'UPDATE',
  DELETE = 'DELETE',
  EXPORT = 'EXPORT',
  LOGIN = 'LOGIN',
  LOGIN_BIOMETRIC = 'LOGIN_BIOMETRIC',
  LOGOUT = 'LOGOUT',
  PASSWORD_RESET = 'PASSWORD_RESET',
  EMAIL_VERIFY = 'EMAIL_VERIFY',
  CONSENT_GRANTED = 'CONSENT_GRANTED',
  CONSENT_REVOKED = 'CONSENT_REVOKED',
  DATA_DELETION_REQUESTED = 'DATA_DELETION_REQUESTED',
  SECURITY_VIOLATION = 'SECURITY_VIOLATION',
}

export enum EntityType {
  USER = 'user',
  CHILD = 'child',
  ACTIVITY = 'activity',
  FAMILY = 'family',
  FAMILY_MEMBER = 'family_member',
  AI_CONVERSATION = 'ai_conversation',
  DEVICE = 'device',
  REFRESH_TOKEN = 'refresh_token',
  NOTIFICATION = 'notification',
  FEEDBACK = 'feedback',
}

@Entity('audit_log')
export class AuditLog {
  @PrimaryColumn({ length: 20 })
  id: string;

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

  @ManyToOne(() => User, { nullable: true, onDelete: 'SET NULL' })
  @JoinColumn({ name: 'user_id' })
  user: User | null;

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

  @Column({
    name: 'entity_type',
    type: 'varchar',
    length: 50,
    enum: EntityType,
  })
  entityType: EntityType;

  @Column({ name: 'entity_id', length: 20, nullable: true })
  entityId: string | null;

  @Column({ type: 'jsonb', nullable: true })
  changes: {
    before?: Record<string, any>;
    after?: Record<string, any>;
  } | null;

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

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

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

  @BeforeInsert()
  generateId() {
    if (!this.id) {
      this.id = `aud_${this.generateNanoId()}`;
    }
  }

  private generateNanoId(): string {
    const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < 12; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }
}
