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

import at.procon.dip.architecture.SchemaNames;
import at.procon.dip.domain.document.entity.Document;
import jakarta.persistence.*;
import java.time.OffsetDateTime;
import java.util.UUID;
import lombok.*;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;

@Entity
@Table(schema = SchemaNames.TIME, name = "time_entry_search_projection", indexes = {
        @Index(name = "idx_time_entry_search_projection_document", columnList = "document_id"),
        @Index(name = "idx_time_entry_search_projection_source", columnList = "source_system, external_id"),
        @Index(name = "idx_time_entry_search_projection_entry_start", columnList = "entry_start"),
        @Index(name = "idx_time_entry_search_projection_person", columnList = "person_external_id"),
        @Index(name = "idx_time_entry_search_projection_activity_type", columnList = "activity_type_id")
})
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class TimeEntrySearchProjection {

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

    @OneToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "time_entry_id", nullable = false, unique = true)
    private TimeEntry timeEntry;

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

    @Enumerated(EnumType.STRING)
    @JdbcTypeCode(SqlTypes.NAMED_ENUM)
    @Column(name = "source_system", nullable = false, columnDefinition = "TIME.time_source_system")
    private TimeSourceSystem sourceSystem;

    @Column(name = "external_id", nullable = false, length = 255)
    private String externalId;

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

    @Column(name = "entry_start")
    private OffsetDateTime entryStart;

    @Column(name = "entry_end")
    private OffsetDateTime entryEnd;

    @Column(name = "duration_seconds")
    private Long durationSeconds;

    @Column(name = "person_external_id", length = 255)
    private String personExternalId;

    @Column(name = "person_display_name", length = 255)
    private String personDisplayName;

    @Column(name = "activity_type_id")
    private Integer activityTypeId;

    @Column(name = "activity_type_code", length = 64)
    private String activityTypeCode;

    @Column(name = "activity_type_name", length = 255)
    private String activityTypeName;

    @Column(name = "record_type", length = 64)
    private String recordType;

    @Column(name = "time_recording_dbk", length = 24)
    private String timeRecordingDbk;

    @Column(name = "time_recording_mcl_id", length = 255)
    private String timeRecordingMclId;

    @Column(name = "time_recording_desc", length = 255)
    private String timeRecordingDesc;

    @Column(name = "time_recording_remark", length = 255)
    private String timeRecordingRemark;

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

    @Column(name = "primary_task_dbk", length = 24)
    private String primaryTaskDbk;

    @Column(name = "primary_task_mcl_id", length = 255)
    private String primaryTaskMclId;

    @Column(name = "primary_task_name", length = 255)
    private String primaryTaskName;

    @Column(name = "primary_task_desc", columnDefinition = "TEXT")
    private String primaryTaskDesc;

    @Column(name = "primary_cost_unit_dbk", length = 24)
    private String primaryCostUnitDbk;

    @Column(name = "primary_cost_unit_mcl_id", length = 255)
    private String primaryCostUnitMclId;

    @Column(name = "primary_cost_unit_name", length = 255)
    private String primaryCostUnitName;

    @Column(name = "primary_cost_unit_desc", length = 255)
    private String primaryCostUnitDesc;

    @Column(name = "primary_contract_dbk", length = 24)
    private String primaryContractDbk;

    @Column(name = "primary_contract_name", length = 255)
    private String primaryContractName;

    @Column(name = "primary_contract_iref", length = 255)
    private String primaryContractIref;

    @Column(name = "primary_contract_position_dbk", length = 24)
    private String primaryContractPositionDbk;

    @Column(name = "primary_contract_position_name", length = 255)
    private String primaryContractPositionName;

    @Column(name = "primary_contract_position_iref", length = 255)
    private String primaryContractPositionIref;

    @Column(name = "primary_organization_dbk", length = 24)
    private String primaryOrganizationDbk;

    @Column(name = "primary_organization_name", length = 255)
    private String primaryOrganizationName;

    @Column(name = "task_ids_text", columnDefinition = "TEXT")
    private String taskIdsText;

    @Column(name = "task_names_text", columnDefinition = "TEXT")
    private String taskNamesText;

    @Column(name = "task_descriptions_text", columnDefinition = "TEXT")
    private String taskDescriptionsText;

    @Column(name = "cost_unit_ids_text", columnDefinition = "TEXT")
    private String costUnitIdsText;

    @Column(name = "cost_unit_names_text", columnDefinition = "TEXT")
    private String costUnitNamesText;

    @Column(name = "cost_unit_descriptions_text", columnDefinition = "TEXT")
    private String costUnitDescriptionsText;

    @Column(name = "contract_names_text", columnDefinition = "TEXT")
    private String contractNamesText;

    @Column(name = "contract_irefs_text", columnDefinition = "TEXT")
    private String contractIrefsText;

    @Column(name = "contract_position_names_text", columnDefinition = "TEXT")
    private String contractPositionNamesText;

    @Column(name = "contract_position_irefs_text", columnDefinition = "TEXT")
    private String contractPositionIrefsText;

    @Column(name = "organization_names_text", columnDefinition = "TEXT")
    private String organizationNamesText;

    @Column(name = "semantic_text", columnDefinition = "TEXT")
    private String semanticText;

    @Column(name = "summary_text", columnDefinition = "TEXT")
    private String summaryText;

    @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();
    }
}
