package com.iqser.red.service.persistence.management.v1.processor.entity.dossier;

import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import com.iqser.red.service.persistence.management.v1.processor.utils.JSONIntegerSetConverter;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.ProcessingStatus;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.WorkflowStatus;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Convert;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "file")
public class FileEntity {

    @Id
    private String id;

    @Column
    private String filename;

    @Column
    @Enumerated(EnumType.STRING)
    private ProcessingStatus processingStatus;

    @Column
    @Enumerated(EnumType.STRING)
    private WorkflowStatus workflowStatus;

    @Column
    private int numberOfPages;

    @Column
    private Long fileSize;

    @Column
    private OffsetDateTime added;

    @Column
    private OffsetDateTime lastUpdated;

    @Column
    private OffsetDateTime deleted;

    @Column
    private OffsetDateTime lastProcessed;

    @Column
    private OffsetDateTime lastLayoutProcessed;

    @Column
    private OffsetDateTime lastIndexed;

    @Column
    private int numberOfAnalyses;

    @Column
    private String assignee;

    @Column
    private String lastReviewer;

    @Column
    private String lastApprover;

    @Column
    private boolean hasRedactions;

    @Column
    private boolean hasHints;

    @Column
    private boolean hasSuggestions;

    @Column
    private boolean hasImages;

    @Column
    private boolean hasUpdates;

    @Column
    private String uploader;

    @Column
    private long dictionaryVersion;

    @Column
    private long rulesVersion;

    @Column
    private long componentRulesVersion;

    @Column
    private long dossierDictionaryVersion;

    @Column
    private long legalBasisVersion;

    @Column
    private OffsetDateTime approvalDate;

    @Column
    private OffsetDateTime lastUploaded;

    @Column
    private long analysisDuration;

    @Column(name = "ocr_start_time")
    private OffsetDateTime ocrStartTime;

    @Column(name = "number_of_pages_to_ocr")
    private Integer numberOfPagesToOCR;

    @Column(name = "number_of_ocred_pages")
    private Integer numberOfOCRedPages;

    @Column(name = "ocr_end_time")
    private OffsetDateTime ocrEndTime;

    @Column
    private boolean hasAnnotationComments;

    @Column
    private boolean excluded;

    @Column
    private boolean excludedFromAutomaticAnalysis;

    @Column
    private OffsetDateTime hardDeletedTime;

    @Column
    private OffsetDateTime lastFileAttributeChange;

    @Column
    private int analysisVersion;

    @Column
    private OffsetDateTime redactionModificationDate;

    @Column
    private OffsetDateTime fileManipulationDate;

    @Column
    private OffsetDateTime lastManualChangeDate;

    @Column
    private boolean hasHighlights;

    @Column(columnDefinition = "text", name = "excluded_pages")
    @Convert(converter = JSONIntegerSetConverter.class)
    private Set<Integer> excludedPages = new HashSet<>();

    @JoinColumn(name = "file_id")
    @Fetch(FetchMode.SUBSELECT)
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<FileAttributeEntity> fileAttributes = new ArrayList<>();

    @Column(name = "dossier_id")
    private String dossierId;

    @Column
    private Integer processingErrorCounter;
    @Column
    private String errorCause;
    @Column
    private String errorQueue;
    @Column
    private String errorService;
    @Column
    private OffsetDateTime errorTimestamp;


    public OffsetDateTime getLastOCRTime() {

        return this.ocrStartTime;
    }


    public boolean isSoftDeleted() {

        return deleted != null;
    }


    public boolean isSoftOrHardDeleted() {

        return deleted != null || hardDeletedTime != null;
    }

}
