# edited by glg
import requests

from pypos.modules.penjualan.services.transaksi_service import TransaksiService


class _FakeResponse:
    def __init__(self, payload=None, status_code=200, text=""):
        self._payload = payload
        self.status_code = status_code
        self.text = text
        self.content = (text or "").encode("utf-8")

    def json(self):
        if self._payload is None:
            raise ValueError("json not available")
        return self._payload


def test_normalize_free_produk_row_enriches_required_legacy_fields():
    service = TransaksiService()
    row, err = service._normalize_free_produk_row(
        {
            "diskon_id": 777,
            "produk_id": 10,
            "produk_nama": "Produk A",
            "free_produk_id": 20,
            "free_produk_nama": "Produk B",
            "free_qty": 2,
            "transaksi_id": 99,
            "transaksi_no": "INV-99",
            "toko_id": 100,
            "oleh_id": 9,
            "oleh_nama": "kasir glg",
            "customer_id": 1,
            "customer_nama": "Tunai",
        },
        default_toko_id=100,
    )
    assert err == ""
    assert row["diskon_id"] == 777
    assert row["nomer_diskon"] == 777
    assert row["ori_produk_id"] == 10
    assert row["ori_produk_nama"] == "Produk A"
    assert row["produk_beli_jml"] == 2
    assert row["minim"] == 1
    assert row["quota_sisa"] == 0
    assert row["dtime"]
    assert row["free_produk_note"]


def test_normalize_free_produk_row_supports_source_alias_fields():
    service = TransaksiService()
    row, err = service._normalize_free_produk_row(
        {
            "nomer_diskon": 8801,
            "produk_id": 11,
            "produk_nama": "Produk Asal",
            "source_produk_id": 11,
            "source_produk_nama": "Produk Asal Alias",
            "free_produk_id": 33,
            "free_produk_nama": "Bonus",
            "free_qty": 1,
            "source_qty": 5,
            "transaksi_id": 1001,
            "transaksi_no": "INV-1001",
            "toko_id": 100,
            "oleh_id": 77,
            "oleh_nama": "kasir",
            "customer_id": 1,
        },
        default_toko_id=100,
    )
    assert err == ""
    assert row["diskon_id"] == 8801
    assert row["nomer_diskon"] == 8801
    assert row["ori_produk_id"] == 11
    assert row["ori_produk_nama"] == "Produk Asal Alias"
    assert row["produk_beli_jml"] == 5


def test_http_post_json_normalizes_reason_from_error_field(monkeypatch):
    service = TransaksiService()

    def _fake_request_with_retry(*args, **kwargs):
        return _FakeResponse(
            payload={
                "status": 0,
                "error": "db_transaction_failed",
                "message": "Gagal menyimpan data diskon",
            }
        )

    monkeypatch.setattr(service, "request_with_retry", _fake_request_with_retry)
    result = service._http_post_json(
        "https://example.test/check",
        data={"dummy": 1},
        timeout=1,
        trace_id="fpq-local-1",
        endpoint_name="check_free_quota",
    )
    assert result["status"] == 0
    assert result["reason"] == "db_transaction_failed"
    assert result["error"] == "db_transaction_failed"
    assert result["error_code"] == "DB_TRANSACTION_FAILED"


def test_http_post_json_http_401_keeps_server_payload(monkeypatch):
    service = TransaksiService()
    server_payload = {
        "status": 0,
        "reason": "unauthorized",
        "message": "Access token tidak valid atau tidak tersedia.",
        "data": None,
        "trace_id": "eusvc-prodiskon-abc123",
        "error": "jwt_type_invalid",
    }

    def _fake_request_with_retry(*args, **kwargs):
        response = _FakeResponse(payload=server_payload, status_code=401)
        raise requests.exceptions.HTTPError(response=response)

    monkeypatch.setattr(service, "request_with_retry", _fake_request_with_retry)
    result = service._http_post_json(
        "https://example.test/save",
        data={},
        files=[],
        timeout=1,
        trace_id="fps-local-1",
        endpoint_name="save_free_produk",
    )
    assert result["status"] == 0
    assert result["reason"] == "unauthorized"
    assert result["error"] == "jwt_type_invalid"
    assert result["trace_id"] == "eusvc-prodiskon-abc123"
    assert result["error_code"] == "FP_API_HTTP_ERROR"


def test_cek_kuota_free_produk_builds_rich_payload(monkeypatch):
    service = TransaksiService()
    captured = {}

    monkeypatch.setattr(
        "pypos.modules.penjualan.services.transaksi_service.build_endpoint_url",
        lambda *args, **kwargs: ("https://example.test/check", ""),
    )
    monkeypatch.setattr(service, "_resolve_toko_id", lambda app_cfg, device_info=None: 100)

    def _fake_http_post_json(url, data, timeout, files=None, trace_id="", endpoint_name=""):
        captured["url"] = url
        captured["data"] = dict(data or {})
        captured["endpoint_name"] = endpoint_name
        return {"status": 1, "reason": ""}

    monkeypatch.setattr(service, "_http_post_json", _fake_http_post_json)
    result = service.cek_kuota_free_produk(
        barang={
            "id": 88,
            "nama": "Produk X",
            "diskon_id": 701,
            "free_produk_id": 11702,
            "free_produk_nama": "Bonus Produk",
            "jumlah_free": 1,
            "jumlah": 9,
            "kelipatan": 1,
            "minim": 9,
            "quota_global": 300,
            "quota_used": 10,
        },
        user_info={"id": 9, "nama": "kasir glg"},
    )

    assert result["status"] == 1
    assert captured["endpoint_name"] == "check_free_quota"
    assert captured["data"]["diskon_id"] == 701
    assert captured["data"]["nomer_diskon"] == 701
    assert captured["data"]["ori_produk_id"] == 88
    assert captured["data"]["free_produk_id"] == 11702
    assert captured["data"]["produk_beli_jml"] == 9
    assert captured["data"]["minim"] == 9
    assert captured["data"]["quota_sisa"] == 290
    assert captured["data"]["oleh_id"] == 9
    assert captured["data"]["oleh_nama"] == "kasir glg"
