# edited by glg
import sqlite3
from types import SimpleNamespace

import pytest

from pypos.modules.penjualan.services.transaksi_penjualan_hotspot_use_case_service import (
    TransaksiPenjualanHotspotUseCaseService,
)

pytestmark = [pytest.mark.unit]


class _TableStub:
    def __init__(self, row_count=1):
        self._row_count = int(row_count or 0)

    def rowCount(self):
        return self._row_count


class _ViewStub:
    def __init__(self, row_count=1):
        self.table_barang = _TableStub(row_count=row_count)
        self._sedang_proses_pembayaran = False
        self.warning_calls = []

    def show_warning(self, title, message):
        self.warning_calls.append((title, message))

    def show_payment_dialog(self, _info, multi_payment_mode=False):
        _ = multi_payment_mode
        return 1, SimpleNamespace(metode="TUNAI")


class _PaymentStateStub:
    def __init__(self):
        self.started = 0
        self.finished = []

    def can_open_payment_dialog(self, row_count, is_processing):
        return int(row_count or 0) > 0 and not bool(is_processing)

    def start_payment_process(self, view):
        self.started += 1
        view._sedang_proses_pembayaran = True

    def finish_payment_process(self, view, success):
        self.finished.append(bool(success))
        view._sedang_proses_pembayaran = False


class _PaymentFlowStub:
    @staticmethod
    def classify_dialog_result(_result_code, _hasil, _dialog_accepted):
        return "single"


class _ControllerStub:
    def __init__(self):
        self.view = _ViewStub(row_count=1)
        self.transaksi_payment_state_service = _PaymentStateStub()
        self.transaksi_payment_flow_service = _PaymentFlowStub()
        self.error_calls = []
        self.logs = []

    @staticmethod
    def _ensure_settlement_guard():
        return True

    @staticmethod
    def _build_info_transaksi_from_table():
        return SimpleNamespace(jenis_item="umum", total_qty=1, total_belanja=1000)

    @staticmethod
    def simpan_transaksi_multi_payment(_hasil):
        return False

    @staticmethod
    def simpan_transaksi_dengan_pembayaran(_hasil):
        raise sqlite3.OperationalError("database is locked")

    def show_error(self, title, message=None, view=None):
        self.error_calls.append((title, message, view))

    def log_info(self, message):
        self.logs.append(("info", str(message)))

    def log_warning(self, message):
        self.logs.append(("warning", str(message)))

    def log_debug(self, message):
        self.logs.append(("debug", str(message)))

    def log_error(self, message):
        self.logs.append(("error", str(message)))


def test_buka_dialog_pembayaran_db_lock_tetap_release_state_dan_show_error():
    service = TransaksiPenjualanHotspotUseCaseService()
    controller = _ControllerStub()

    service.buka_dialog_pembayaran(controller=controller, dialog_accepted=1)

    assert controller.transaksi_payment_state_service.started == 1
    assert controller.transaksi_payment_state_service.finished == [False]
    assert controller.view._sedang_proses_pembayaran is False
    assert controller.error_calls
    assert "Kode: TRX_SAVE_FLOW_UNHANDLED" in str(controller.error_calls[0][1] or "")
