from pypos.core.utils.audit_logger import log_audit


class TransaksiSaveService:
    def __init__(self, db_path, transaksi_model, voucher_model):
        self.db_path = db_path
        self.transaksi_model = transaksi_model
        self.voucher_model = voucher_model

    def save_with_audit(
        self,
        *,
        transaksi_data,
        detail_data,
        transaksi_data_dict,
        audit_message,
        voucher_callback=None,
        trace_id="",
    ):
        # edited by glg
        # Hook voucher dijalankan pre-commit agar transaksi + voucher usage atomik.
        precommit_hook = None
        if callable(voucher_callback):
            def _precommit_hook(transaksi_id, conn):
                voucher_callback(transaksi_id, conn)
            precommit_hook = _precommit_hook

        transaksi_id, arr_free_produk = self.transaksi_model.simpan_transaksi(
            transaksi_data,
            detail_data,
            transaksi_data_dict,
            precommit_hook=precommit_hook,
            trace_id=trace_id,
        )
        audit_text = str(audit_message or "").strip()
        trace_text = str(trace_id or "").strip()
        if trace_text:
            audit_text = f"{audit_text} | trace_id={trace_text}" if audit_text else f"trace_id={trace_text}"
        log_audit(
            self.db_path,
            transaksi_data_dict["oleh_id"],
            "INSERT",
            "transaksi",
            transaksi_id,
            audit_text,
        )
        return transaksi_id, arr_free_produk

    def apply_voucher_usage_single(self, transaksi_id, hasil_pembayaran, conn=None):
        code = getattr(hasil_pembayaran, "voucher_code", "") or ""
        amount = float(getattr(hasil_pembayaran, "voucher_amount", 0) or 0)
        if not code or amount <= 0:
            return True, ""
        return self.voucher_model.apply_usage(code, str(transaksi_id), amount, conn=conn)

    def apply_voucher_usage_multi(self, transaksi_id, payment_list, conn=None):
        code = ""
        amount = 0.0
        for payment in payment_list or []:
            code = getattr(payment, "voucher_code", "") or ""
            amount = float(getattr(payment, "voucher_amount", 0) or 0)
            if code and amount > 0:
                break
        if not code or amount <= 0:
            return True, ""
        return self.voucher_model.apply_usage(code, str(transaksi_id), amount, conn=conn)
