# edited by glg
import sqlite3
import tempfile
import unittest
from pathlib import Path

from pypos.modules.penjualan.services.settlement_mutation_lock_service import (
    SettlementMutationLockService,
)


def _seed_settlement_history_schema(db_path: str, *, with_map_table: bool = False):
    conn = sqlite3.connect(db_path)
    cur = conn.cursor()
    cur.execute(
        """
        CREATE TABLE IF NOT EXISTS settlement_history (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            data_transaksi_id TEXT
        )
        """
    )
    if with_map_table:
        cur.execute(
            """
            CREATE TABLE IF NOT EXISTS settlement_history_transaksi_map (
                settlement_history_id INTEGER NOT NULL,
                transaksi_id INTEGER NOT NULL,
                PRIMARY KEY (settlement_history_id, transaksi_id)
            )
            """
        )
    conn.commit()
    conn.close()


class SettlementMutationLockServiceTests(unittest.TestCase):
    def test_get_lock_map_menggunakan_map_table_jika_tersedia(self):
        with tempfile.TemporaryDirectory() as td:
            db_path = str(Path(td) / "lock_map.db")
            _seed_settlement_history_schema(db_path, with_map_table=True)

            conn = sqlite3.connect(db_path)
            cur = conn.cursor()
            cur.execute(
                "INSERT INTO settlement_history (data_transaksi_id) VALUES (?)",
                ("[]",),
            )
            settlement_history_id = int(cur.lastrowid or 0)
            cur.execute(
                """
                INSERT INTO settlement_history_transaksi_map (settlement_history_id, transaksi_id)
                VALUES (?, ?), (?, ?)
                """,
                (settlement_history_id, 101, settlement_history_id, 102),
            )
            conn.commit()
            conn.close()

            service = SettlementMutationLockService(db_path=db_path)
            result = service.get_lock_map([101, 102, 103])

            self.assertEqual(result, {101: True, 102: True, 103: False})

    def test_get_lock_map_fallback_ke_blob_settlement_history(self):
        with tempfile.TemporaryDirectory() as td:
            db_path = str(Path(td) / "lock_blob.db")
            _seed_settlement_history_schema(db_path, with_map_table=False)

            conn = sqlite3.connect(db_path)
            cur = conn.cursor()
            cur.execute(
                "INSERT INTO settlement_history (data_transaksi_id) VALUES (?)",
                ("[201, 202, \"x\"]",),
            )
            conn.commit()
            conn.close()

            service = SettlementMutationLockService(db_path=db_path)
            result = service.get_lock_map([201, 202, 203])

            self.assertEqual(result, {201: True, 202: True, 203: False})

    def test_get_lock_map_fail_safe_lock_semua_jika_query_error(self):
        with tempfile.TemporaryDirectory() as td:
            db_path = str(Path(td) / "lock_error.db")
            _seed_settlement_history_schema(db_path, with_map_table=False)

            service = SettlementMutationLockService(db_path=db_path)
            service._refresh_settlement_txn_cache = lambda _cursor: (_ for _ in ()).throw(
                sqlite3.OperationalError("forced_settlement_query_error")
            )
            result = service.get_lock_map([301, 302])

            self.assertEqual(result, {301: True, 302: True})


if __name__ == "__main__":
    unittest.main()
