package com.pablotj.ai.chat.domain.model;

import java.util.Objects;

/**
 * Value Object representing a conversation summary.
 */
public final class ConversationSummary {

    private static final int MAX_TITLE_LENGTH = 100;
    private static final int MAX_DESCRIPTION_LENGTH = 500;
    private static final String DEFAULT_TITLE = "New Conversation";

    private final String title;
    private final String description;

    public ConversationSummary(String title) {
        this.title = title;
        this.description = "";
    }

    private ConversationSummary(String title, String description) {
        this.title = validateAndNormalizeTitle(title);
        this.description = validateAndNormalizeDescription(description);
    }

    public static ConversationSummary of(String title, String description) {
        return new ConversationSummary(title, description);
    }

    public static ConversationSummary defaultSummary() {
        return new ConversationSummary(DEFAULT_TITLE, null);
    }

    public static ConversationSummary fromFirstMessage(MessageContent firstMessage) {
        String title = generateTitleFromContent(firstMessage.getText());
        return new ConversationSummary(title, null);
    }

    private static String generateTitleFromContent(String content) {
        if (content == null || content.trim().isEmpty()) {
            return DEFAULT_TITLE;
        }

        String normalized = content.trim();
        if (normalized.length() <= 50) {
            return normalized;
        }

        // Find a good breaking point (space, punctuation)
        int breakPoint = findBreakPoint(normalized, 50);
        return normalized.substring(0, breakPoint) + "...";
    }

    private static int findBreakPoint(String text, int maxLength) {
        if (text.length() <= maxLength) {
            return text.length();
        }

        // Look for space or punctuation near the max length
        for (int i = maxLength; i > maxLength - 20 && i > 0; i--) {
            char c = text.charAt(i);
            if (Character.isWhitespace(c) || c == '.' || c == ',' || c == ';' || c == '!') {
                return i;
            }
        }

        return maxLength;
    }

    private String validateAndNormalizeTitle(String title) {
        if (title == null || title.trim().isEmpty()) {
            return DEFAULT_TITLE;
        }

        String normalized = title.trim();
        if (normalized.length() > MAX_TITLE_LENGTH) {
            normalized = normalized.substring(0, MAX_TITLE_LENGTH - 3) + "...";
        }

        return normalized;
    }

    private String validateAndNormalizeDescription(String description) {
        if (description == null) {
            return null;
        }

        String normalized = description.trim();
        if (normalized.isEmpty()) {
            return null;
        }

        if (normalized.length() > MAX_DESCRIPTION_LENGTH) {
            normalized = normalized.substring(0, MAX_DESCRIPTION_LENGTH - 3) + "...";
        }

        return normalized;
    }

    public String getTitle() {
        return title;
    }

    public String getDescription() {
        return description;
    }

    public boolean hasDescription() {
        return description != null && !description.isEmpty();
    }

    public ConversationSummary withDescription(String newDescription) {
        return new ConversationSummary(this.title, newDescription);
    }

    public ConversationSummary withTitle(String newTitle) {
        return new ConversationSummary(newTitle, this.description);
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(title, description);
    }

    @Override
    public String toString() {
        return hasDescription() ?
                String.format("%s - %s", title, description) :
                title;
    }
}
