package com.storycove.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import org.hibernate.annotations.CreationTimestamp;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;

import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

@Entity
@Table(name = "tags")
public class Tag {
    
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;
    
    @NotBlank(message = "Tag name is required")
    @Size(max = 100, message = "Tag name must not exceed 100 characters")
    @Column(nullable = false, unique = true)
    private String name;
    
    @Size(max = 7, message = "Color must be a valid hex color code")
    @Column(length = 7)
    private String color; // hex color like #3B82F6
    
    @Size(max = 500, message = "Description must not exceed 500 characters")
    @Column(length = 500)
    private String description;
    
    
    @ManyToMany(mappedBy = "tags")
    @JsonBackReference("story-tags")
    private Set<Story> stories = new HashSet<>();
    
    @ManyToMany(mappedBy = "tags")
    @JsonBackReference("collection-tags")
    private Set<Collection> collections = new HashSet<>();
    
    @OneToMany(mappedBy = "canonicalTag", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonManagedReference("tag-aliases")
    private Set<TagAlias> aliases = new HashSet<>();
    
    @CreationTimestamp
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;
    
    public Tag() {}
    
    public Tag(String name) {
        this.name = name;
    }
    
    public Tag(String name, String color, String description) {
        this.name = name;
        this.color = color;
        this.description = description;
    }
    
    
    
    // Getters and Setters
    public UUID getId() {
        return id;
    }
    
    public void setId(UUID id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getColor() {
        return color;
    }
    
    public void setColor(String color) {
        this.color = color;
    }
    
    public String getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    
    public Set<Story> getStories() {
        return stories;
    }
    
    public void setStories(Set<Story> stories) {
        this.stories = stories;
    }
    
    public Set<Collection> getCollections() {
        return collections;
    }
    
    public void setCollections(Set<Collection> collections) {
        this.collections = collections;
    }
    
    public Set<TagAlias> getAliases() {
        return aliases;
    }
    
    public void setAliases(Set<TagAlias> aliases) {
        this.aliases = aliases;
    }
    
    public LocalDateTime getCreatedAt() {
        return createdAt;
    }
    
    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Tag)) return false;
        Tag tag = (Tag) o;
        return id != null && id.equals(tag.id);
    }
    
    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
    
    @Override
    public String toString() {
        return "Tag{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}