# edited by glg
import pytest

from pypos.modules.penjualan.services.transaksi_barang_mutation_use_case_service import (
    TransaksiBarangMutationUseCaseService,
)

pytestmark = [pytest.mark.unit]


def test_build_apply_plan_success():
    service = TransaksiBarangMutationUseCaseService()

    plan = service.build_apply_plan(
        id_barang="101",
        tambahan_qty=2,
        find_barang_row_callback=lambda _pid: (3, 1),
        compute_total_qty_callback=lambda add, old: int(add or 0) + int(old or 0),
        ensure_admin_authorized_callback=lambda _pid, _qty: True,
        find_barang_detail_callback=lambda pid, qty: {"id": pid, "jumlah": qty, "harga": 1000},
        is_valid_harga_callback=lambda detail: bool(detail.get("harga")),
    )

    assert plan["ok"] is True
    assert plan["reason"] == "ok"
    assert plan["existing_row"] == 3
    assert int(plan["jumlah_total"]) == 3
    assert plan["barang_detail"]["id"] == "101"


def test_build_apply_plan_invalid_harga():
    service = TransaksiBarangMutationUseCaseService()

    plan = service.build_apply_plan(
        id_barang="102",
        tambahan_qty=1,
        find_barang_row_callback=lambda _pid: (None, 0),
        compute_total_qty_callback=lambda add, old: int(add or 0) + int(old or 0),
        ensure_admin_authorized_callback=lambda _pid, _qty: True,
        find_barang_detail_callback=lambda pid, qty: {"id": pid, "jumlah": qty, "harga": 0},
        is_valid_harga_callback=lambda detail: bool(detail.get("harga")),
    )

    assert plan["ok"] is False
    assert plan["reason"] == "invalid_harga"
    assert plan["barang_detail"]["id"] == "102"


def test_build_manual_qty_plan_invalid_qty():
    service = TransaksiBarangMutationUseCaseService()

    plan = service.build_manual_qty_plan(
        id_barang="201",
        prev_qty=4,
        qty_text="-1",
        normalize_manual_qty_callback=lambda _text: (False, 1),
        ensure_admin_authorized_callback=lambda _pid, _qty: True,
        find_barang_detail_callback=lambda _pid, _qty: {"id": "201"},
        is_valid_harga_callback=lambda _detail: True,
    )

    assert plan["ok"] is False
    assert plan["reason"] == "invalid_qty"
    assert int(plan["revert_qty"]) == 1


def test_build_manual_qty_plan_no_change():
    service = TransaksiBarangMutationUseCaseService()

    plan = service.build_manual_qty_plan(
        id_barang="202",
        prev_qty=5,
        qty_text="5",
        normalize_manual_qty_callback=lambda _text: (True, 5),
        ensure_admin_authorized_callback=lambda _pid, _qty: True,
        find_barang_detail_callback=lambda _pid, _qty: {"id": "202"},
        is_valid_harga_callback=lambda _detail: True,
    )

    assert plan["ok"] is False
    assert plan["reason"] == "no_change"
    assert int(plan["revert_qty"]) == 5


def test_build_manual_qty_plan_admin_rejected():
    service = TransaksiBarangMutationUseCaseService()

    plan = service.build_manual_qty_plan(
        id_barang="203",
        prev_qty=2,
        qty_text="10",
        normalize_manual_qty_callback=lambda _text: (True, 10),
        ensure_admin_authorized_callback=lambda _pid, _qty: False,
        find_barang_detail_callback=lambda _pid, _qty: {"id": "203"},
        is_valid_harga_callback=lambda _detail: True,
    )

    assert plan["ok"] is False
    assert plan["reason"] == "admin_rejected"
    assert int(plan["revert_qty"]) == 2


def test_build_manual_qty_plan_success():
    service = TransaksiBarangMutationUseCaseService()

    plan = service.build_manual_qty_plan(
        id_barang="204",
        prev_qty=2,
        qty_text="7",
        normalize_manual_qty_callback=lambda _text: (True, 7),
        ensure_admin_authorized_callback=lambda _pid, _qty: True,
        find_barang_detail_callback=lambda pid, qty: {"id": pid, "jumlah": qty, "harga": 1200},
        is_valid_harga_callback=lambda detail: bool(detail.get("harga")),
    )

    assert plan["ok"] is True
    assert plan["reason"] == "ok"
    assert int(plan["jumlah"]) == 7
    assert plan["barang_detail"]["id"] == "204"
