package com.storycove.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import com.fasterxml.jackson.annotation.JsonBackReference;

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

@Entity
@Table(name = "reading_positions", indexes = {
    @Index(name = "idx_reading_position_story", columnList = "story_id")
})
public class ReadingPosition {
    
    @Id
    @GeneratedValue(strategy = GenerationType.UUID)
    private UUID id;
    
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "story_id", nullable = false)
    @JsonBackReference("story-reading-positions")
    private Story story;
    
    @Column(name = "chapter_index")
    private Integer chapterIndex;
    
    @Column(name = "chapter_title")
    private String chapterTitle;
    
    @Column(name = "word_position")
    private Integer wordPosition;
    
    @Column(name = "character_position")
    private Integer characterPosition;
    
    @Column(name = "percentage_complete")
    private Double percentageComplete;
    
    @Column(name = "epub_cfi", columnDefinition = "TEXT")
    private String epubCfi;
    
    @Column(name = "context_before", length = 500)
    private String contextBefore;
    
    @Column(name = "context_after", length = 500)
    private String contextAfter;
    
    @CreationTimestamp
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;
    
    @UpdateTimestamp
    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;
    
    public ReadingPosition() {}
    
    public ReadingPosition(Story story) {
        this.story = story;
        this.chapterIndex = 0;
        this.wordPosition = 0;
        this.characterPosition = 0;
        this.percentageComplete = 0.0;
    }
    
    public ReadingPosition(Story story, Integer chapterIndex, Integer wordPosition) {
        this.story = story;
        this.chapterIndex = chapterIndex;
        this.wordPosition = wordPosition;
        this.characterPosition = 0;
        this.percentageComplete = 0.0;
    }
    
    public void updatePosition(Integer chapterIndex, Integer wordPosition, Integer characterPosition) {
        this.chapterIndex = chapterIndex;
        this.wordPosition = wordPosition;
        this.characterPosition = characterPosition;
        calculatePercentageComplete();
    }
    
    public void updatePositionWithCfi(String epubCfi, Integer chapterIndex, Integer wordPosition) {
        this.epubCfi = epubCfi;
        this.chapterIndex = chapterIndex;
        this.wordPosition = wordPosition;
        calculatePercentageComplete();
    }
    
    private void calculatePercentageComplete() {
        if (story != null && story.getWordCount() != null && story.getWordCount() > 0) {
            int totalWords = story.getWordCount();
            int currentPosition = (chapterIndex != null ? chapterIndex * 1000 : 0) + 
                                (wordPosition != null ? wordPosition : 0);
            this.percentageComplete = Math.min(100.0, (double) currentPosition / totalWords * 100);
        }
    }
    
    public boolean isAtBeginning() {
        return (chapterIndex == null || chapterIndex == 0) && 
               (wordPosition == null || wordPosition == 0);
    }
    
    public boolean isCompleted() {
        return percentageComplete != null && percentageComplete >= 95.0;
    }
    
    // Getters and Setters
    public UUID getId() {
        return id;
    }
    
    public void setId(UUID id) {
        this.id = id;
    }
    
    public Story getStory() {
        return story;
    }
    
    public void setStory(Story story) {
        this.story = story;
    }
    
    public Integer getChapterIndex() {
        return chapterIndex;
    }
    
    public void setChapterIndex(Integer chapterIndex) {
        this.chapterIndex = chapterIndex;
    }
    
    public String getChapterTitle() {
        return chapterTitle;
    }
    
    public void setChapterTitle(String chapterTitle) {
        this.chapterTitle = chapterTitle;
    }
    
    public Integer getWordPosition() {
        return wordPosition;
    }
    
    public void setWordPosition(Integer wordPosition) {
        this.wordPosition = wordPosition;
    }
    
    public Integer getCharacterPosition() {
        return characterPosition;
    }
    
    public void setCharacterPosition(Integer characterPosition) {
        this.characterPosition = characterPosition;
    }
    
    public Double getPercentageComplete() {
        return percentageComplete;
    }
    
    public void setPercentageComplete(Double percentageComplete) {
        this.percentageComplete = percentageComplete;
    }
    
    public String getEpubCfi() {
        return epubCfi;
    }
    
    public void setEpubCfi(String epubCfi) {
        this.epubCfi = epubCfi;
    }
    
    public String getContextBefore() {
        return contextBefore;
    }
    
    public void setContextBefore(String contextBefore) {
        this.contextBefore = contextBefore;
    }
    
    public String getContextAfter() {
        return contextAfter;
    }
    
    public void setContextAfter(String contextAfter) {
        this.contextAfter = contextAfter;
    }
    
    public LocalDateTime getCreatedAt() {
        return createdAt;
    }
    
    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }
    
    public LocalDateTime getUpdatedAt() {
        return updatedAt;
    }
    
    public void setUpdatedAt(LocalDateTime updatedAt) {
        this.updatedAt = updatedAt;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof ReadingPosition)) return false;
        ReadingPosition that = (ReadingPosition) o;
        return id != null && id.equals(that.id);
    }
    
    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
    
    @Override
    public String toString() {
        return "ReadingPosition{" +
                "id=" + id +
                ", storyId=" + (story != null ? story.getId() : null) +
                ", chapterIndex=" + chapterIndex +
                ", wordPosition=" + wordPosition +
                ", percentageComplete=" + percentageComplete +
                '}';
    }
}