package at.procon.dip.domain.document.entity;

import at.procon.dip.architecture.SchemaNames;
import at.procon.dip.ingestion.mail.MailProviderType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.PrePersist;
import jakarta.persistence.PreUpdate;
import jakarta.persistence.Table;
import java.time.OffsetDateTime;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Entity
@Table(schema = SchemaNames.DOC, name = "doc_mail_message", indexes = {
        @Index(name = "idx_doc_mail_message_source_id", columnList = "source_id"),
        @Index(name = "idx_doc_mail_message_message_id", columnList = "message_id"),
        @Index(name = "idx_doc_mail_message_thread_key", columnList = "thread_key"),
        @Index(name = "idx_doc_mail_message_provider_identity", columnList = "provider_type, account_key, folder_key, provider_message_key")
})
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DocumentMailMessage {

    @Id
    @Column(name = "document_id", nullable = false)
    private UUID documentId;

    @OneToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "document_id", nullable = false, insertable = false, updatable = false)
    private Document document;

    @Column(name = "source_id")
    private UUID sourceId;

    @Enumerated(EnumType.STRING)
    @Column(name = "provider_type", nullable = false, length = 64)
    @Builder.Default
    private MailProviderType providerType = MailProviderType.GENERIC;

    @Column(name = "account_key", length = 255)
    private String accountKey;

    @Column(name = "folder_key", length = 255)
    private String folderKey;

    @Column(name = "provider_message_key", length = 500)
    private String providerMessageKey;

    @Column(name = "provider_thread_key", length = 500)
    private String providerThreadKey;

    @Column(name = "message_id", length = 1000)
    private String messageId;

    @Column(name = "in_reply_to", length = 1000)
    private String inReplyTo;

    @Column(name = "references_header", columnDefinition = "TEXT")
    private String referencesHeader;

    @Column(name = "thread_key", length = 1000)
    private String threadKey;

    @Column(name = "subject", length = 1000)
    private String subject;

    @Column(name = "normalized_subject", length = 1000)
    private String normalizedSubject;

    @Column(name = "from_display_name", length = 500)
    private String fromDisplayName;

    @Column(name = "from_email", length = 500)
    private String fromEmail;

    @Column(name = "from_raw", length = 1000)
    private String fromRaw;

    @Column(name = "reply_to_raw", columnDefinition = "TEXT")
    private String replyToRaw;

    @Column(name = "sent_at")
    private OffsetDateTime sentAt;

    @Column(name = "received_at")
    private OffsetDateTime receivedAt;

    @Column(name = "raw_message_hash", length = 64)
    private String rawMessageHash;

    @Column(name = "raw_header_hash", length = 64)
    private String rawHeaderHash;

    @Builder.Default
    @Column(name = "created_at", nullable = false, updatable = false)
    private OffsetDateTime createdAt = OffsetDateTime.now();

    @Builder.Default
    @Column(name = "updated_at", nullable = false)
    private OffsetDateTime updatedAt = OffsetDateTime.now();

    @PrePersist
    protected void onCreate() {
        createdAt = OffsetDateTime.now();
        updatedAt = OffsetDateTime.now();
    }

    @PreUpdate
    protected void onUpdate() {
        updatedAt = OffsetDateTime.now();
    }
}
