"""Aplikasi Inventaris SQLite - antarmuka pengguna."""

import sqlite3

import database


def format_rupiah(nilai: int) -> str:
    """Format angka menjadi teks rupiah, contoh 15000 menjadi Rp15.000."""
    return "Rp" + f"{nilai:,}".replace(",", ".")


def cetak_tabel(rows: list) -> None:
    """Cetak daftar produk sebagai tabel rapi."""
    print(f"{'ID':<3} {'Nama':<18} {'Kategori':<10} {'Harga':>10} {'Stok':>4}")
    print(f"{'---':<3} {'-' * 18} {'-' * 10} {'-' * 10} {'-' * 4}")
    for row in rows:
        print(
            f"{row['id']:<3} {row['nama']:<18} {row['kategori']:<10} "
            f"{format_rupiah(row['harga']):>10} {row['stok']:>4}"
        )


def baca_angka(prompt: str) -> int:
    """Minta masukan angka bulat, ulangi sampai masukan sah."""
    while True:
        teks = input(prompt).strip()
        try:
            return int(teks)
        except ValueError:
            print("Masukkan angka bulat, misalnya 15000.")


def menu_tambah() -> None:
    nama = input("Nama produk: ").strip()
    kategori = input("Kategori: ").strip()
    harga = baca_angka("Harga (Rp): ")
    stok = baca_angka("Stok awal: ")

    try:
        database.validasi_produk(nama, kategori, harga, stok)
    except ValueError as galat:
        print(f"Gagal: {galat}")
        return

    try:
        id_baru = database.tambah_produk(nama, kategori, harga, stok)
    except sqlite3.IntegrityError:
        print(f"Produk dengan nama '{nama}' sudah terdaftar.")
        return

    print(f"Produk '{nama}' tersimpan dengan id {id_baru}.")


def menu_lihat() -> None:
    rows = database.lihat_produk()
    if not rows:
        print("Belum ada produk.")
        return
    cetak_tabel(rows)


def menu_ubah_harga() -> None:
    produk_id = baca_angka("ID produk: ")
    harga_baru = baca_angka("Harga baru (Rp): ")
    if database.perbarui_harga(produk_id, harga_baru):
        print("Harga berhasil diperbarui.")
    else:
        print(f"Tidak ada produk dengan id {produk_id}.")


def menu_sesuaikan_stok() -> None:
    produk_id = baca_angka("ID produk: ")
    perubahan = baca_angka("Perubahan stok (boleh negatif): ")
    keterangan = input("Keterangan: ").strip() or "penyesuaian manual"

    try:
        database.sesuaikan_stok(produk_id, perubahan, keterangan)
    except ValueError as galat:
        print(f"Gagal: {galat}")
        return
    except sqlite3.IntegrityError:
        print("Gagal: penyesuaian membuat stok negatif. Transaksi dibatalkan.")
        return

    print("Stok berhasil disesuaikan.")


def menu_hapus() -> None:
    produk_id = baca_angka("ID produk: ")
    if database.hapus_produk(produk_id):
        print("Produk berhasil dihapus.")
    else:
        print(f"Tidak ada produk dengan id {produk_id}.")


def menu_riwayat() -> None:
    produk_id = baca_angka("ID produk: ")
    produk = database.ambil_produk(produk_id)
    if produk is None:
        print(f"Tidak ada produk dengan id {produk_id}.")
        return

    rows = database.lihat_riwayat(produk_id)
    if not rows:
        print(f"Belum ada riwayat untuk '{produk['nama']}'.")
        return

    print(f"Riwayat untuk '{produk['nama']}':")
    print(f"{'Waktu':<21} {'Perubahan':>9}  Keterangan")
    for row in rows:
        print(f"{row['waktu']:<21} {row['perubahan']:>+9}  {row['keterangan']}")


def tampilkan_menu() -> None:
    print()
    print("=== Aplikasi Inventaris ===")
    print("1. Tambah produk")
    print("2. Lihat semua produk")
    print("3. Ubah harga")
    print("4. Sesuaikan stok (+/-)")
    print("5. Hapus produk")
    print("6. Riwayat produk")
    print("0. Keluar")


def main() -> None:
    database.inisialisasi()
    print("Database siap. Selamat datang!")

    while True:
        tampilkan_menu()
        try:
            pilihan = input("Pilih menu: ").strip()
        except EOFError:
            print()
            break

        if pilihan == "0":
            print("Sampai jumpa!")
            break

        match pilihan:
            case "1":
                menu_tambah()
            case "2":
                menu_lihat()
            case "3":
                menu_ubah_harga()
            case "4":
                menu_sesuaikan_stok()
            case "5":
                menu_hapus()
            case "6":
                menu_riwayat()
            case _:
                print("Pilihan tidak dikenal.")


if __name__ == "__main__":
    main()
