import time
import numpy as np

class ScreenCapture:
    """
    Module chụp màn hình hiệu năng cao dựa trên DirectX Desktop Duplication API (dxcam).
    Đạt tốc độ từ 60 FPS đến 200+ FPS trên Windows với GPU NVIDIA.
    """
    def __init__(self, target_fps: int = 60, region: tuple = None):
        self.target_fps = target_fps
        self.region = region
        self.camera = None
        self.sct = None
        self._init_camera()

    def _init_camera(self):
        try:
            import dxcam
            # Khởi tạo DXCam gắn trực tiếp với GPU chính (1660S)
            # DXCam sử dụng Ring Buffer cố định trong VRAM, tự ghi đè frame mới mà không tích lũy RAM
            self.camera = dxcam.create(output_color="BGR")
            print("[ScreenCapture] DXCam initialized successfully (DirectX GPU Duplication).")
        except Exception as e:
            print(f"[ScreenCapture] DXCam unavailable: {e}. Falling back to mss.")
            import mss
            self.sct = mss.mss()
            self.camera = None

    def grab(self) -> np.ndarray:
        """
        Lấy 1 frame ảnh mới nhất từ bộ nhớ đệm.
        Frame nằm hoàn toàn trên RAM/VRAM, KHÔNG ghi file ra đĩa và được tự động giải phóng ở mỗi vòng lặp.
        """
        if self.camera is not None:
            frame = self.camera.grab(region=self.region)
            if frame is not None:
                return frame

        # Fallback mss dùng đối tượng sct khởi tạo sẵn (không tạo/hủy handler liên tục)
        if self.sct is not None:
            monitor = self.sct.monitors[1] if self.region is None else {
                "top": self.region[1],
                "left": self.region[0],
                "width": self.region[2] - self.region[0],
                "height": self.region[3] - self.region[1]
            }
            img = np.array(self.sct.grab(monitor))
            return img[:, :, :3]  # Bỏ kênh Alpha, lấy BGR
        return None

    def release(self):
        """
        Giải phóng triệt để tài nguyên DirectX handle và bộ nhớ đệm.
        """
        if self.camera is not None:
            try:
                del self.camera
                self.camera = None
            except Exception:
                pass
        if self.sct is not None:
            try:
                self.sct.close()
                self.sct = None
            except Exception:
                pass
        print("[ScreenCapture] Resources released successfully.")

    def __del__(self):
        self.release()

