package dev.lions.unionflow.server.entity;

import dev.lions.unionflow.server.api.enums.communication.ConversationType;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Entité Conversation pour le système de messagerie UnionFlow.
 * Représente un fil de discussion entre membres.
 *
 * @author UnionFlow Team
 * @version 1.0
 * @since 2026-03-16
 */
@Entity
@Table(name = "conversations", indexes = {
    @Index(name = "idx_conversation_organisation", columnList = "organisation_id"),
    @Index(name = "idx_conversation_type", columnList = "type"),
    @Index(name = "idx_conversation_archived", columnList = "is_archived"),
    @Index(name = "idx_conversation_created", columnList = "date_creation")
})
@Getter
@Setter
public class Conversation extends BaseEntity {

    /**
     * Nom de la conversation
     */
    @Column(name = "name", nullable = false, length = 255)
    private String name;

    /**
     * Description optionnelle
     */
    @Column(name = "description", length = 1000)
    private String description;

    /**
     * Type de conversation (INDIVIDUAL, GROUP, BROADCAST, ANNOUNCEMENT)
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "type", nullable = false, length = 20)
    private ConversationType type;

    /**
     * Organisation associée (optionnelle)
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "organisation_id")
    private Organisation organisation;

    /**
     * URL de l'avatar de la conversation
     */
    @Column(name = "avatar_url", length = 500)
    private String avatarUrl;

    /**
     * Conversation muette
     */
    @Column(name = "is_muted", nullable = false)
    private Boolean isMuted = false;

    /**
     * Conversation épinglée
     */
    @Column(name = "is_pinned", nullable = false)
    private Boolean isPinned = false;

    /**
     * Conversation archivée
     */
    @Column(name = "is_archived", nullable = false)
    private Boolean isArchived = false;

    /**
     * Métadonnées additionnelles (JSON)
     */
    @Column(name = "metadata", columnDefinition = "TEXT")
    private String metadata;

    /**
     * Date de dernière mise à jour
     */
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    /**
     * Participants de la conversation (many-to-many)
     */
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(
        name = "conversation_participants",
        joinColumns = @JoinColumn(name = "conversation_id"),
        inverseJoinColumns = @JoinColumn(name = "membre_id")
    )
    private List<Membre> participants = new ArrayList<>();

    /**
     * Messages de la conversation (one-to-many)
     */
    @OneToMany(mappedBy = "conversation", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Message> messages = new ArrayList<>();

    /**
     * Met à jour le timestamp
     */
    @PreUpdate
    protected void onUpdate() {
        this.updatedAt = LocalDateTime.now();
    }
}
