package com.pablotj.ai.chat.infrastructure.persistence.entity;

import jakarta.persistence.CascadeType;
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.OneToMany;
import jakarta.persistence.OrderBy;
import jakarta.persistence.Table;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

/**
 * JPA entity representing a conversation in the database.
 */
@Entity
@Table(name = "conversations", indexes = {
        @Index(name = "idx_conversation_uuid", columnList = "uuid", unique = true),
        @Index(name = "idx_conversation_status", columnList = "status"),
        @Index(name = "idx_conversation_created_at", columnList = "created_at")
})
public class ConversationEntity {

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

    @Column(name = "uuid", nullable = false, unique = true, length = 36)
    private String uuid;

    @Column(name = "title", nullable = false, length = 100)
    private String title;

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

    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private ConversationStatusEntity status;

    @CreationTimestamp
    @Column(name = "created_at", nullable = false, updatable = false)
    private Instant createdAt;

    @UpdateTimestamp
    @Column(name = "updated_at", nullable = false)
    private Instant updatedAt;

    @OneToMany(mappedBy = "conversation", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
    @OrderBy("createdAt ASC")
    private List<ConversationMessageEntity> messages = new ArrayList<>();

    // Constructors
    public ConversationEntity() {
    }

    public ConversationEntity(String uuid, String title, String description, ConversationStatusEntity status) {
        this.uuid = uuid;
        this.title = title;
        this.description = description;
        this.status = status;
    }

    // Helper methods
    public void addMessage(ConversationMessageEntity message) {
        messages.add(message);
        message.setConversation(this);
    }

    public void removeMessage(ConversationMessageEntity message) {
        messages.remove(message);
        message.setConversation(null);
    }

    public int getMessageCount() {
        return messages.size();
    }

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUuid() {
        return uuid;
    }

    public void setUuid(String uuid) {
        this.uuid = uuid;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public ConversationStatusEntity getStatus() {
        return status;
    }

    public void setStatus(ConversationStatusEntity status) {
        this.status = status;
    }

    public Instant getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(Instant createdAt) {
        this.createdAt = createdAt;
    }

    public Instant getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(Instant updatedAt) {
        this.updatedAt = updatedAt;
    }

    public List<ConversationMessageEntity> getMessages() {
        return messages;
    }

    public void setMessages(List<ConversationMessageEntity> messages) {
        this.messages = messages;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        ConversationEntity that = (ConversationEntity) obj;
        return Objects.equals(uuid, that.uuid);
    }

    @Override
    public int hashCode() {
        return Objects.hash(uuid);
    }

    @Override
    public String toString() {
        return String.format("ConversationEntity{uuid='%s', title='%s', status=%s}", uuid, title, status);
    }
}
