package de.cannamanage.domain.entity;

import de.cannamanage.domain.enums.AuditEventType;
import jakarta.persistence.*;

import java.time.Instant;
import java.util.UUID;

/**
 * Immutable audit log entry.
 * No setters for fields post-persist — once written, never changed.
 * 10-year retention per KCanG compliance requirements.
 */
@Entity
@Table(name = "audit_events")
public class AuditEvent {

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    @Column(name = "id", nullable = false, updatable = false)
    private UUID id;

    @Enumerated(EnumType.STRING)
    @Column(name = "event_type", nullable = false, updatable = false, length = 50)
    private AuditEventType eventType;

    @Column(name = "entity_type", nullable = false, updatable = false, length = 50)
    private String entityType;

    @Column(name = "entity_id", updatable = false)
    private UUID entityId;

    @Column(name = "actor_id", nullable = false, updatable = false)
    private UUID actorId;

    @Column(name = "actor_name", nullable = false, updatable = false)
    private String actorName;

    @Column(name = "actor_role", nullable = false, updatable = false, length = 20)
    private String actorRole;

    @Column(name = "description", nullable = false, updatable = false, columnDefinition = "TEXT")
    private String description;

    @Column(name = "metadata", updatable = false, columnDefinition = "jsonb")
    private String metadata;

    @Column(name = "ip_address", updatable = false, length = 45)
    private String ipAddress;

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

    @Column(name = "tenant_id", nullable = false, updatable = false)
    private UUID tenantId;

    protected AuditEvent() {
        // JPA
    }

    private AuditEvent(Builder builder) {
        this.eventType = builder.eventType;
        this.entityType = builder.entityType;
        this.entityId = builder.entityId;
        this.actorId = builder.actorId;
        this.actorName = builder.actorName;
        this.actorRole = builder.actorRole;
        this.description = builder.description;
        this.metadata = builder.metadata;
        this.ipAddress = builder.ipAddress;
        this.timestamp = Instant.now();
        this.tenantId = builder.tenantId;
    }

    public static Builder builder() {
        return new Builder();
    }

    // Read-only getters
    public UUID getId() { return id; }
    public AuditEventType getEventType() { return eventType; }
    public String getEntityType() { return entityType; }
    public UUID getEntityId() { return entityId; }
    public UUID getActorId() { return actorId; }
    public String getActorName() { return actorName; }
    public String getActorRole() { return actorRole; }
    public String getDescription() { return description; }
    public String getMetadata() { return metadata; }
    public String getIpAddress() { return ipAddress; }
    public Instant getTimestamp() { return timestamp; }
    public UUID getTenantId() { return tenantId; }

    public static class Builder {
        private AuditEventType eventType;
        private String entityType;
        private UUID entityId;
        private UUID actorId;
        private String actorName;
        private String actorRole;
        private String description;
        private String metadata;
        private String ipAddress;
        private UUID tenantId;

        public Builder eventType(AuditEventType eventType) { this.eventType = eventType; return this; }
        public Builder entityType(String entityType) { this.entityType = entityType; return this; }
        public Builder entityId(UUID entityId) { this.entityId = entityId; return this; }
        public Builder actorId(UUID actorId) { this.actorId = actorId; return this; }
        public Builder actorName(String actorName) { this.actorName = actorName; return this; }
        public Builder actorRole(String actorRole) { this.actorRole = actorRole; return this; }
        public Builder description(String description) { this.description = description; return this; }
        public Builder metadata(String metadata) { this.metadata = metadata; return this; }
        public Builder ipAddress(String ipAddress) { this.ipAddress = ipAddress; return this; }
        public Builder tenantId(UUID tenantId) { this.tenantId = tenantId; return this; }

        public AuditEvent build() {
            return new AuditEvent(this);
        }
    }
}
