"""Kalkulator Terminal - penanganan error dan testing.

Bagian 4: logika hitung dipisahkan sebagai fungsi murni,
error ditangani pada satu lapisan, dan seluruh logika diuji dengan pytest.
"""


def hitung(a: float, op: str, b: float) -> float:
    """Kembalikan hasil a <op> b untuk op salah satu dari + - * /.

    Membangkitkan ZeroDivisionError bila op adalah "/" dan b bernilai 0,
    serta ValueError bila op tidak dikenal.
    """
    if op == "+":
        return a + b
    if op == "-":
        return a - b
    if op == "*":
        return a * b
    if op == "/":
        return a / b
    raise ValueError(f"operator tidak dikenal: {op!r}")


def tampilkan_menu():
    """Cetak daftar operasi yang tersedia."""
    print("=== Kalkulator Terminal ===")
    print("1. Tambah")
    print("2. Kurang")
    print("3. Kali")
    print("4. Bagi")
    print("5. Keluar")


PILIHAN_KE_OPERATOR = {
    "1": "+",
    "2": "-",
    "3": "*",
    "4": "/",
}


def baca_pilihan():
    """Baca nomor operasi; ulangi sampai pengguna memasukkan 1-5."""
    while True:
        pilihan = input("Pilih operasi (1-5): ").strip()
        if pilihan in ("1", "2", "3", "4", "5"):
            return pilihan
        print(f"Pilihan '{pilihan}' tidak dikenal. Masukkan angka 1-5.")


def baca_angka(label):
    """Baca satu angka; ulangi sampai input dapat dikonversi menjadi float."""
    while True:
        teks = input(f"{label}: ").strip()
        try:
            return float(teks)
        except ValueError:
            print(f"'{teks}' bukan angka yang valid. Coba lagi.")


def tanya_lagi():
    """Tanyakan apakah pengguna ingin menghitung lagi; terima hanya y atau t."""
    while True:
        jawaban = input("Hitung lagi? (y/t): ").strip().lower()
        if jawaban in ("y", "t"):
            return jawaban == "y"
        print("Jawaban harus 'y' atau 't'.")


def main():
    """Titik masuk program: koordinasi input, hitung, dan output."""
    while True:
        tampilkan_menu()
        pilihan = baca_pilihan()

        if pilihan == "5":
            break

        op = PILIHAN_KE_OPERATOR[pilihan]
        a = baca_angka("Angka pertama")
        b = baca_angka("Angka kedua")

        try:
            hasil = hitung(a, op, b)
        except ZeroDivisionError:
            print("Error: pembagian dengan nol tidak diperbolehkan.")
        else:
            print(f"Hasil: {a:g} {op} {b:g} = {hasil:g}")

        if not tanya_lagi():
            break

    print("Terima kasih telah menggunakan Kalkulator Terminal.")


if __name__ == "__main__":
    main()
