# edited by glg
import sqlite3

from pypos.core.utils.db_helper import connect_sqlite
from pypos.modules.penjualan.errors import TransaksiSaveError


class TransaksiSimpanUseCaseService:
    """
    Use-case service untuk proses simpan transaksi atomik.
    """

    def __init__(self, transaksi_model):
        self.transaksi_model = transaksi_model

    @staticmethod
    def _trace_tag(trace_id: str = "") -> str:
        text = str(trace_id or "").strip()
        return text or "-"

    def execute(
        self,
        *,
        transaksi_data,
        detail_data,
        transaksi_data_dict,
        precommit_hook=None,
        trace_id: str = "",
    ):
        _ = transaksi_data
        model = self.transaksi_model
        trace_tag = self._trace_tag(trace_id)
        counter, nomer2 = model._prepare_simpan_transaksi_identity(transaksi_data_dict)
        model._log_simpan_transaksi_context(
            counter,
            nomer2,
            transaksi_data_dict,
            trace_id=trace_tag,
        )
        conn = connect_sqlite(model.db_path)
        try:
            cursor = conn.cursor()
            model.log_debug(f"[TRX_SAVE][{trace_tag}] simpan_transaksi insert master mulai")
            model._ensure_pembayaran_non_tunai_column(cursor)
            transaksi_id, arr_free_produk = model._execute_simpan_transaksi_flow(
                cursor=cursor,
                conn=conn,
                detail_data=detail_data,
                transaksi_data_dict=transaksi_data_dict,
                precommit_hook=precommit_hook,
            )
            conn.commit()
            model.log_info(
                f"[TRX_SAVE][{trace_tag}] commit sukses transaksi_id={int(transaksi_id or 0)}"
            )
            return transaksi_id, arr_free_produk
        except TransaksiSaveError:
            model._rollback_connection(conn)
            raise
        except sqlite3.Error as exc:
            model._rollback_connection(conn)
            raise TransaksiSaveError(
                "TRX_SAVE_DB_ERROR",
                "Gagal menyimpan transaksi ke database.",
                cause=exc,
            ) from exc
        except (TypeError, ValueError, KeyError) as exc:
            model._rollback_connection(conn)
            raise TransaksiSaveError(
                "TRX_SAVE_DATA_ERROR",
                "Data transaksi tidak valid saat proses simpan.",
                cause=exc,
            ) from exc
        except (AttributeError, RuntimeError) as exc:
            model._rollback_connection(conn)
            raise TransaksiSaveError(
                "TRX_SAVE_UNEXPECTED_ERROR",
                "Terjadi kesalahan saat menyimpan transaksi.",
                cause=exc,
            ) from exc
        finally:
            conn.close()
