import importlib
import os
import sys
import tempfile
import unittest
from types import SimpleNamespace


def load_real_zlapi():
    original_modules = {
        name: module
        for name, module in sys.modules.items()
        if name == "zlapi" or name.startswith("zlapi.")
    }
    for name in original_modules:
        sys.modules.pop(name, None)

    try:
        package = importlib.import_module("zlapi")
        models = importlib.import_module("zlapi.models")
        return package.ZaloAPI, models.ThreadType
    finally:
        for name in list(sys.modules):
            if name == "zlapi" or name.startswith("zlapi."):
                sys.modules.pop(name, None)
        sys.modules.update(original_modules)


ZaloAPI, ThreadType = load_real_zlapi()


class ZaloImageUploadTests(unittest.TestCase):
    def test_upload_image_uses_basename_for_absolute_path(self):
        client = object.__new__(ZaloAPI)
        client._imei = "test-imei"
        client._encode = lambda params: params
        client._decode = lambda data: {
            "error_code": 0,
            "data": {
                "normalUrl": "https://example.test/normal.png",
                "thumbUrl": "https://example.test/thumb.png",
                "hdUrl": "https://example.test/hd.png",
            },
        }
        captured = {}

        def fake_post(url, params, files):
            captured["params"] = params
            captured["files"] = files
            return SimpleNamespace(json=lambda: {"error_code": 0, "data": "encoded"})

        client._post = fake_post

        with tempfile.TemporaryDirectory() as temp_dir:
            image_path = os.path.join(temp_dir, "payment-qr.png")
            with open(image_path, "wb") as image_file:
                image_file.write(b"test-image")

            try:
                client._uploadImage(image_path, "group-id", ThreadType.GROUP)
            finally:
                for _, uploaded_file in captured.get("files", []):
                    uploaded_file.close()

        self.assertEqual(captured["params"]["params"]["fileName"], "payment-qr.png")

    def test_upload_image_closes_file_after_request(self):
        client = object.__new__(ZaloAPI)
        client._imei = "test-imei"
        client._encode = lambda params: params
        client._decode = lambda data: {
            "error_code": 0,
            "data": {
                "normalUrl": "https://example.test/normal.png",
                "thumbUrl": "https://example.test/thumb.png",
                "hdUrl": "https://example.test/hd.png",
            },
        }
        captured = {}

        def fake_post(url, params, files):
            captured["uploaded_file"] = files[0][1]
            return SimpleNamespace(json=lambda: {"error_code": 0, "data": "encoded"})

        client._post = fake_post

        with tempfile.TemporaryDirectory() as temp_dir:
            image_path = os.path.join(temp_dir, "payment-qr.png")
            with open(image_path, "wb") as image_file:
                image_file.write(b"test-image")

            client._uploadImage(image_path, "group-id", ThreadType.GROUP)

        self.assertTrue(captured["uploaded_file"].closed)


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