"""Utilitas teks sederhana untuk mengolah string sehari-hari.

Package ini memuat tiga function: ``slugify`` untuk membuat slug URL,
``hitung_kata`` untuk menghitung jumlah kata, dan ``ringkas`` untuk
memotong teks panjang.
"""

import re
import unicodedata

__version__ = "0.1.0"

__all__ = ["hitung_kata", "ringkas", "slugify"]


def slugify(text: str) -> str:
    """Mengubah teks menjadi slug yang aman untuk URL.

    Function ini menormalisasi teks ke bentuk NFKD, membuang tanda
    diakritik (misalnya ``é`` menjadi ``e``), mengubah seluruh huruf
    menjadi lowercase, lalu mengganti setiap rangkaian karakter yang
    bukan huruf kecil atau angka dengan satu tanda hubung.

    Args:
        text: Teks yang akan diubah menjadi slug.

    Returns:
        Slug dalam lowercase yang dipisah tanda hubung. String kosong
        dikembalikan apabila ``text`` tidak memuat huruf atau angka
        sama sekali.

    Examples:
        >>> slugify("Belajar Python Dasar!")
        'belajar-python-dasar'
    """
    normalized = unicodedata.normalize("NFKD", text)
    ascii_text = normalized.encode("ascii", "ignore").decode("ascii")
    lower_text = ascii_text.lower()
    slug = re.sub(r"[^a-z0-9]+", "-", lower_text)
    return slug.strip("-")


def hitung_kata(text: str) -> int:
    """Menghitung jumlah kata pada sebuah teks.

    Kata didefinisikan sebagai rangkaian karakter yang dipisahkan
    whitespace apa pun — spasi, tab, maupun newline — sehingga
    whitespace berulang di awal, tengah, atau akhir teks diabaikan.

    Args:
        text: Teks yang akan dihitung jumlah katanya.

    Returns:
        Jumlah kata pada ``text``; 0 untuk teks kosong atau teks yang
        hanya berisi whitespace.

    Examples:
        >>> hitung_kata("Belajar Python setiap hari")
        4
    """
    return len(text.split())


def ringkas(text: str, panjang: int, akhir: str = "...") -> str:
    """Memotong teks agar tidak melebihi panjang tertentu.

    Teks yang panjangnya tidak melebihi ``panjang`` dikembalikan tanpa
    perubahan. Teks yang lebih panjang dipotong lalu diberi akhiran
    ``akhir`` sehingga panjang total hasilnya tepat ``panjang``.

    Args:
        text: Teks sumber yang akan dipotong.
        panjang: Panjang maksimum teks hasil.
        akhir: Akhiran yang ditempelkan pada teks yang terpotong.

    Returns:
        Teks asli apabila ``len(text) <= panjang``; teks terpotong
        berakhiran ``akhir`` pada kondisi lainnya.

    Examples:
        >>> ringkas("Belajar Python di Course ini sampai tuntas", 20)
        'Belajar Python di...'
    """
    if len(text) <= panjang:
        return text
    if panjang <= len(akhir):
        return text[:panjang]
    return text[: panjang - len(akhir)].rstrip() + akhir
