# edited by glg
from types import SimpleNamespace

import pytest

from pypos.modules.penjualan.controllers.load_transaksi_controller import LoadTransaksiController
from pypos.modules.penjualan.services.load_transaksi_apply_service import (
    LoadTransaksiApplyService,
)
from pypos.modules.penjualan.services.load_transaksi_service import LoadTransaksiService

pytestmark = [pytest.mark.unit, pytest.mark.critical_flow]


def _new_load_controller_stub():
    ctrl = LoadTransaksiController.__new__(LoadTransaksiController)
    ctrl.service = LoadTransaksiService()
    ctrl.load_apply_service = LoadTransaksiApplyService()
    ctrl._selected_context = {"source": "local"}
    ctrl.transaksi_terpilih_id = 5
    ctrl.log_warning = lambda *_args, **_kwargs: None
    ctrl.log_error = lambda *_args, **_kwargs: None
    return ctrl


def test_load_dipilih_local_success_cleanup_and_accept():
    ctrl = _new_load_controller_stub()
    accepted = []
    loaded = []
    deleted_ids = []
    warnings = []

    ctrl.view = SimpleNamespace(accept=lambda: accepted.append(True))
    ctrl.show_warning = lambda title, message: warnings.append((title, message))
    ctrl.load_list_transaksi = lambda *args, **kwargs: None
    ctrl.transaksi_controller = SimpleNamespace(
        load_transaksi_ke_view=lambda *args, **kwargs: loaded.append(
            {"args": args, "kwargs": kwargs}
        )
    )
    ctrl.model = SimpleNamespace(
        get_transaksi_header=lambda _transaksi_id: (2, "Member A", 5, 11, 120000),
        get_detail_transaksi=lambda _transaksi_id: [("1", "Produk A", 10000, 2, 0, "pcs")],
        get_transaksi_row=lambda _transaksi_id: {"nomer": "INV-5"},
        delete_transaksi_by_id=lambda transaksi_id: deleted_ids.append(int(transaksi_id)),
    )

    ctrl.load_dipilih()

    assert not warnings
    assert loaded
    assert deleted_ids == [5]
    assert accepted == [True]


def test_load_dipilih_local_cleanup_fail_tetap_warning_parsial():
    ctrl = _new_load_controller_stub()
    accepted = []
    loaded = []
    warnings = []
    list_reload_calls = []

    ctrl.view = SimpleNamespace(accept=lambda: accepted.append(True))
    ctrl.show_warning = lambda title, message: warnings.append((title, message))
    ctrl.load_list_transaksi = lambda *args, **kwargs: list_reload_calls.append(
        {"args": args, "kwargs": kwargs}
    )
    ctrl.transaksi_controller = SimpleNamespace(
        load_transaksi_ke_view=lambda *args, **kwargs: loaded.append(
            {"args": args, "kwargs": kwargs}
        )
    )
    ctrl.model = SimpleNamespace(
        get_transaksi_header=lambda _transaksi_id: (1, "Tunai", 0, 11, 50000),
        get_detail_transaksi=lambda _transaksi_id: [("2", "Produk B", 25000, 2, 0, "pcs")],
        get_transaksi_row=lambda _transaksi_id: {"nomer": "INV-5"},
        delete_transaksi_by_id=lambda _transaksi_id: (_ for _ in ()).throw(
            ValueError("hapus ditolak")
        ),
    )

    ctrl.load_dipilih()

    assert loaded
    assert not accepted
    assert warnings
    assert warnings[0][0] == "Load Parsial"
    assert list_reload_calls


def test_load_dipilih_local_invalid_id_tampilkan_warning_pilih_transaksi():
    ctrl = _new_load_controller_stub()
    warnings = []
    ctrl.transaksi_terpilih_id = "invalid-id"
    ctrl.view = SimpleNamespace(accept=lambda: (_ for _ in ()).throw(AssertionError("accept tidak boleh dipanggil")))
    ctrl.show_warning = lambda title, message: warnings.append((title, message))

    ctrl.load_dipilih()

    assert warnings
    assert warnings[0][0] == "Pilih Transaksi"
