import os
import cv2
import numpy as np

_CASCADE = None

def _get_cascade():
    global _CASCADE
    if _CASCADE is None:
        here = os.path.dirname(__file__)
        xml_path = os.path.join(here, "cascades", "haarcascade_frontalface_default.xml")
        if not os.path.exists(xml_path):
            raise RuntimeError(f"Cannot find cascade file: {xml_path}")
        c = cv2.CascadeClassifier(xml_path)
        if c.empty():
            raise RuntimeError(f"Failed to load cascade from: {xml_path}")
        _CASCADE = c
    return _CASCADE

def detect_faces_bgr(frame_bgr, scale_factor=1.15, min_neighbors=5, min_size=(40, 40)):
    gray = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (3, 3), 0)
    return _get_cascade().detectMultiScale(
        gray,
        scaleFactor=scale_factor,
        minNeighbors=min_neighbors,
        minSize=min_size,
        flags=cv2.CASCADE_SCALE_IMAGE,
    )

def build_soft_face_mask(shape_hw, faces, enlarge=0.45, feather=45):
    h, w = shape_hw
    mask = np.zeros((h, w), dtype=np.uint8)
    for (x, y, fw, fh) in faces:
        cx, cy = x + fw // 2, y + fh // 2
        rx, ry = int(fw * (0.5 + enlarge)), int(fh * (0.7 + enlarge))
        cv2.ellipse(mask, (cx, cy), (rx, ry), 0, 0, 360, 255, -1)
    if feather > 0:
        k = feather if feather % 2 == 1 else feather + 1
        mask = cv2.GaussianBlur(mask, (k, k), 0)
    return mask
