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.JsonManagedReference;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;

@Entity
@Table(name = "series")
public class Series {
    
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;
    
    @NotBlank(message = "Series name is required")
    @Size(max = 255, message = "Series name must not exceed 255 characters")
    @Column(nullable = false)
    private String name;
    
    @Size(max = 1000, message = "Series description must not exceed 1000 characters")
    @Column(length = 1000)
    private String description;
    
    @OneToMany(mappedBy = "series", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @OrderBy("volume ASC")
    @JsonManagedReference("series-stories")
    private List<Story> stories = new ArrayList<>();
    
    @CreationTimestamp
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;
    
    
    public Series() {}
    
    public Series(String name) {
        this.name = name;
    }
    
    public Series(String name, String description) {
        this.name = name;
        this.description = description;
    }
    
    public void addStory(Story story) {
        stories.add(story);
        story.setSeries(this);
    }
    
    public void removeStory(Story story) {
        stories.remove(story);
        story.setSeries(null);
    }
    
    
    public Story getNextStory(Story currentStory) {
        if (currentStory.getVolume() == null) return null;

        return stories.stream()
                .filter(story -> story.getVolume() != null)
                .filter(story -> story.getVolume() > currentStory.getVolume())
                .min(Comparator.comparingDouble(Story::getVolume))
                .orElse(null);
    }

    public Story getPreviousStory(Story currentStory) {
        if (currentStory.getVolume() == null) return null;

        return stories.stream()
                .filter(story -> story.getVolume() != null)
                .filter(story -> story.getVolume() < currentStory.getVolume())
                .max(Comparator.comparingDouble(Story::getVolume))
                .orElse(null);
    }
    
    // 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 getDescription() {
        return description;
    }
    
    public void setDescription(String description) {
        this.description = description;
    }
    
    
    public List<Story> getStories() {
        return stories;
    }
    
    public void setStories(List<Story> stories) {
        this.stories = stories;
    }
    
    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 Series)) return false;
        Series series = (Series) o;
        return id != null && id.equals(series.id);
    }
    
    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
    
    @Override
    public String toString() {
        return "Series{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}