package de.effigenix.infrastructure.audit;

import de.effigenix.application.usermanagement.AuditEvent;
import jakarta.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.OffsetDateTime;
import java.time.ZoneOffset;

/**
 * JPA Entity for Audit Logs.
 *
 * HACCP/GoBD Compliance:
 * - Immutable after creation (no update allowed)
 * - Retention: 10 years (gesetzlich)
 * - Contains: Who (actor), What (event), When (timestamp), Where (IP), How (user agent)
 */
@Entity
@Table(name = "audit_logs", indexes = {
        @Index(name = "idx_audit_event", columnList = "event"),
        @Index(name = "idx_audit_actor", columnList = "performed_by"),
        @Index(name = "idx_audit_timestamp", columnList = "timestamp"),
        @Index(name = "idx_audit_entity", columnList = "entity_id")
})
@EntityListeners(AuditingEntityListener.class)
public class AuditLogEntity {

    @Id
    @Column(name = "id", nullable = false, length = 36)
    private String id;

    @Enumerated(EnumType.STRING)
    @Column(name = "event", nullable = false, length = 100)
    private AuditEvent event;

    @Column(name = "entity_id", length = 36)
    private String entityId;

    @Column(name = "performed_by", length = 36)
    private String performedBy;  // ActorId

    @Column(name = "details", length = 2000)
    private String details;

    @Column(name = "timestamp", nullable = false)
    private OffsetDateTime timestamp;

    @Column(name = "ip_address", length = 45)  // IPv6 max length
    private String ipAddress;

    @Column(name = "user_agent", length = 500)
    private String userAgent;

    @CreatedDate
    @Column(name = "created_at", nullable = false, updatable = false)
    private OffsetDateTime createdAt;

    // JPA requires no-arg constructor
    protected AuditLogEntity() {
    }

    public AuditLogEntity(
            String id,
            AuditEvent event,
            String entityId,
            String performedBy,
            String details,
            OffsetDateTime timestamp,
            String ipAddress,
            String userAgent
    ) {
        this.id = id;
        this.event = event;
        this.entityId = entityId;
        this.performedBy = performedBy;
        this.details = details;
        this.timestamp = timestamp;
        this.ipAddress = ipAddress;
        this.userAgent = userAgent;
        this.createdAt = OffsetDateTime.now(ZoneOffset.UTC);
    }

    // Getters only (immutable after creation)
    public String getId() {
        return id;
    }

    public AuditEvent getEvent() {
        return event;
    }

    public String getEntityId() {
        return entityId;
    }

    public String getPerformedBy() {
        return performedBy;
    }

    public String getDetails() {
        return details;
    }

    public OffsetDateTime getTimestamp() {
        return timestamp;
    }

    public String getIpAddress() {
        return ipAddress;
    }

    public String getUserAgent() {
        return userAgent;
    }

    public OffsetDateTime getCreatedAt() {
        return createdAt;
    }
}
