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

import at.procon.dip.architecture.SchemaNames;
import at.procon.dip.domain.document.RepresentationType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.PrePersist;
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;

/**
 * Search-oriented text derived from a canonical document.
 */
@Entity
@Table(schema = SchemaNames.DOC, name = "doc_text_representation", indexes = {
        @Index(name = "idx_doc_text_repr_document", columnList = "document_id"),
        @Index(name = "idx_doc_text_repr_content", columnList = "content_id"),
        @Index(name = "idx_doc_text_repr_type", columnList = "representation_type"),
        @Index(name = "idx_doc_text_repr_primary", columnList = "is_primary")
})
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class DocumentTextRepresentation {

    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "content_id")
    private DocumentContent content;

    @Enumerated(EnumType.STRING)
    @Column(name = "representation_type", nullable = false, length = 64)
    private RepresentationType representationType;

    @Column(name = "builder_key", length = 255)
    private String builderKey;

    @Column(name = "language_code", length = 16)
    private String languageCode;

    @Column(name = "token_count")
    private Integer tokenCount;

    @Column(name = "char_count")
    private Integer charCount;

    @Column(name = "chunk_index")
    private Integer chunkIndex;

    @Column(name = "chunk_start_offset")
    private Integer chunkStartOffset;

    @Column(name = "chunk_end_offset")
    private Integer chunkEndOffset;

    @Builder.Default
    @Column(name = "is_primary", nullable = false)
    private boolean primaryRepresentation = false;

    @Column(name = "text_body", columnDefinition = "TEXT", nullable = false)
    private String textBody;

    @Column(name = "search_config", length = 64)
    private String searchConfig;

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

    @PrePersist
    protected void onCreate() {
        createdAt = OffsetDateTime.now();
        if (charCount == null && textBody != null) {
            charCount = textBody.length();
        }
    }
}
