package de.gecheckt.pdf.umbenenner.application.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import org.junit.jupiter.api.Test;

/**
 * Unit tests for {@link DocumentTextLimiter}.
 */
class DocumentTextLimiterTest {

    @Test
    void limit_textShorterThanMax_returnsTextUnchanged() {
        String text = "short text";
        String result = DocumentTextLimiter.limit(text, 100);
        assertThat(result).isEqualTo(text);
    }

    @Test
    void limit_textExactlyMax_returnsTextUnchanged() {
        String text = "exactly ten";  // 11 chars
        String result = DocumentTextLimiter.limit(text, 11);
        assertThat(result).isEqualTo(text);
        assertThat(result).hasSize(11);
    }

    @Test
    void limit_textLongerThanMax_returnsTruncatedText() {
        String text = "Hello, World!";
        String result = DocumentTextLimiter.limit(text, 5);
        assertThat(result).isEqualTo("Hello");
        assertThat(result).hasSize(5);
    }

    @Test
    void limit_maxCharactersOne_returnsSingleChar() {
        String text = "ABC";
        String result = DocumentTextLimiter.limit(text, 1);
        assertThat(result).isEqualTo("A");
    }

    @Test
    void limit_emptyText_returnsEmptyString() {
        String result = DocumentTextLimiter.limit("", 100);
        assertThat(result).isEmpty();
    }

    @Test
    void limit_emptyTextWithMinMax_returnsEmptyString() {
        String result = DocumentTextLimiter.limit("", 1);
        assertThat(result).isEmpty();
    }

    @Test
    void limit_textWithUnicodeCharacters_respectsCharCount() {
        // German umlauts are single chars in Java
        String text = "Rechnungsübersicht";  // 18 chars
        String result = DocumentTextLimiter.limit(text, 10);
        assertThat(result).hasSize(10);
        assertThat(result).startsWith("Rechnungs");
    }

    @Test
    void limit_nullText_throwsNullPointerException() {
        assertThatThrownBy(() -> DocumentTextLimiter.limit(null, 100))
                .isInstanceOf(NullPointerException.class)
                .hasMessage("text must not be null");
    }

    @Test
    void limit_maxCharactersZero_throwsIllegalArgumentException() {
        assertThatThrownBy(() -> DocumentTextLimiter.limit("text", 0))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("maxCharacters must be >= 1");
    }

    @Test
    void limit_negativeMaxCharacters_throwsIllegalArgumentException() {
        assertThatThrownBy(() -> DocumentTextLimiter.limit("text", -5))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessageContaining("maxCharacters must be >= 1");
    }

    @Test
    void limit_doesNotModifyOriginalText() {
        String original = "This is the original document text that is long";
        String limited = DocumentTextLimiter.limit(original, 10);

        // The original String object is unchanged (Java Strings are immutable)
        assertThat(limited).isNotSameAs(original);
        assertThat(limited).hasSize(10);
    }
}
