import layoutparser as lp
import numpy as np

CLASS_MAP = {
    0: "Text", 1: "Title", 2: "List",
    3: "Table", 4: "Figure", 5: "Advertisement",
}

class LayoutDetector:
    def __init__(self):
        try:
            # Detectron2 PubLayNet — swap with custom DocLayNet/YOLOv11 weights
            self.model = lp.Detectron2LayoutModel(
                config_path="lp://PubLayNet/mask_rcnn_X_101_32x8d_FPN_3x/config",
                extra_config=["MODEL.ROI_HEADS.SCORE_THRESH_TEST", 0.55],
                label_map={0:"Text",1:"Title",2:"List",3:"Table",4:"Figure"},
            )
        except Exception:
            self.model = None
        # Optional secondary ad classifier (custom-trained)
        self.ad_classifier = AdClassifier()

    def detect(self, image: np.ndarray):
        if self.model is None:
            # Fallback to single block if detectron2 isn't installed
            h, w = image.shape[:2]
            return [{
                "type": "Text",
                "bbox": [0, 0, w, h],
                "score": 1.0,
                "is_ad": False
            }]
            
        layout = self.model.detect(image)
        blocks = []
        for b in layout:
            box = b.coordinates  # (x1,y1,x2,y2)
            block = {
                "type": b.type,
                "bbox": [int(c) for c in box],
                "score": float(b.score),
            }
            block["is_ad"] = self.ad_classifier.predict(image, box)
            blocks.append(block)
        return blocks


class AdClassifier:
    """
    Ads rarely match column grids and contain logos/price patterns.
    Train a lightweight CNN (MobileNet) on labeled ad/non-ad crops,
    OR use heuristics + LLM verification. Stub below.
    """
    def predict(self, image, box) -> bool:
        # Heuristic placeholder: replace with trained model
        return False
