# edited by glg
import json
import os
import sqlite3
import tempfile
from pathlib import Path

import pytest

from pypos.modules.penjualan.models.settlement_model import SettlementModel
from pypos.modules.sinkronisasi.services.settlement_direct_service import SettlementDirectService
from pypos.modules.sinkronisasi.services.transaction_export_service import TransactionExportService


pytestmark = [pytest.mark.integration]


def _runtime_appdata_dir():
    appdata = os.environ.get("APPDATA") or os.environ.get("LOCALAPPDATA")
    if not appdata:
        return None
    return Path(appdata) / "PyPOS"


def _runtime_db_path():
    root = _runtime_appdata_dir()
    if root is None:
        return None
    db_path = root / "db" / "beta_sb_pos_sqlite.db"
    if not db_path.is_file():
        return None
    return db_path


def _runtime_endpoint_config_path():
    root = _runtime_appdata_dir()
    if root is None:
        return None
    cfg_path = root / "config.json"
    if not cfg_path.is_file():
        return None
    return cfg_path


def _backup_sqlite_database(src_path, dst_path):
    src_conn = sqlite3.connect("file:%s?mode=ro" % str(src_path), uri=True)
    dst_conn = sqlite3.connect(str(dst_path))
    try:
        src_conn.backup(dst_conn)
    finally:
        dst_conn.close()
        src_conn.close()


def _load_endpoint_config():
    cfg_path = _runtime_endpoint_config_path()
    if cfg_path is None:
        return {}
    with open(str(cfg_path), "r", encoding="utf-8") as fp:
        raw = json.load(fp)
    return raw if isinstance(raw, dict) else {}


def test_runtime_snapshot_settlement_atomic_dan_kontrak_startpoint_direct():
    runtime_db = _runtime_db_path()
    if runtime_db is None:
        pytest.skip("Runtime DB PyPOS lokal tidak ditemukan.")

    endpoint_cfg = _load_endpoint_config()
    if not endpoint_cfg:
        pytest.skip("config.json endpoint PyPOS lokal tidak ditemukan.")

    assert str(endpoint_cfg.get("api_base_url") or "").strip() != ""
    assert str(endpoint_cfg.get("ep_settlement_direct") or "").strip() != ""

    with tempfile.TemporaryDirectory(ignore_cleanup_errors=True) as td:
        snapshot_db = Path(td) / "runtime_snapshot.db"
        _backup_sqlite_database(runtime_db, snapshot_db)

        model = SettlementModel(str(snapshot_db))
        pending_ids = model.get_transaksi_ids_belum_settle(include_legacy_non_tunai=True)
        if not pending_ids:
            pytest.skip("Tidak ada transaksi pending settlement pada snapshot DB lokal.")

        conn = model.connect()
        conn.row_factory = sqlite3.Row
        try:
            cur = conn.cursor()
            placeholders = ",".join(["?"] * len(pending_ids))
            cur.execute(
                "SELECT id, oleh_id, oleh_nama, cabang_id, cabang_nama FROM transaksi WHERE id IN (%s) ORDER BY datetime(dtime) ASC LIMIT 1"
                % placeholders,
                tuple(int(v) for v in pending_ids),
            )
            first_row = cur.fetchone()
            assert first_row is not None
            kasir_id = int(first_row["oleh_id"] or 0)
            kasir_nama = str(first_row["oleh_nama"] or "Kasir Runtime")
            cabang_id = int(first_row["cabang_id"] or 0)
            cabang_nama = str(first_row["cabang_nama"] or "")
        finally:
            conn.close()

        totals = model.hitung_total_per_metode_by_ids(pending_ids)
        total_tunai = float((totals or {}).get("Tunai") or 0.0)

        result = model.execute_settlement_atomic(
            kasir_id=kasir_id,
            kasir_nama=kasir_nama,
            cabang_id=cabang_id,
            cabang_nama=cabang_nama,
            transaksi_list=[{"tanggal": "runtime-snapshot", "kasir": kasir_nama}],
            approval_id=999,
            approval_nama="runtime-check",
            transaksi_ids_override=pending_ids,
            admin="runtime-check",
            total_disetor=total_tunai,
            trace_id="runtime-snapshot-contract",
        )

        assert bool((result or {}).get("ok")) is True, str(result)
        assert str((result or {}).get("counter") or "").startswith("ST-")

        export_service = TransactionExportService(db_path=str(snapshot_db))
        payload = export_service.build_direct_settlement_payload(
            transaksi_ids=list((result or {}).get("transaksi_ids") or pending_ids),
            settlement_counter=str((result or {}).get("counter") or ""),
        )

        assert isinstance(payload, dict) and payload
        assert str(payload.get("dtime") or "").strip() != ""
        assert isinstance(payload.get("data"), dict) and bool(payload.get("data"))
        assert int(payload.get("cabang_id") or 0) >= 0
        assert str(payload.get("device_id") or "").strip() != ""

        direct_service = SettlementDirectService(
            export_service=export_service,
            endpoint_config_reader=lambda: endpoint_cfg,
            enabled_getter=lambda: True,
            auth_required_getter=lambda: True,
        )
        resolved_url = direct_service._resolve_url()
        assert str(resolved_url).startswith(str(endpoint_cfg.get("api_base_url")))
        assert str(endpoint_cfg.get("ep_settlement_direct")) in str(resolved_url)
