#!/opt/homebrew/bin/python3.11
"""
Filter Candidates for "Inverted Jenny" (Blue + Red)
"""

import cv2
import numpy as np
import os
import glob

UUID = "384b0ff44aaaa1f1"
BASE_DIR = f"output/{UUID}/florence2_results"

print("🎨 Filtering candidates for Blue + Red signature...")

# Load all object_in_hand images
candidates = glob.glob(os.path.join(BASE_DIR, "object_in_hand_*.jpg"))
print(f"Found {len(candidates)} candidates.")

matches = []

for img_path in candidates:
    img = cv2.imread(img_path)
    if img is None:
        continue

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # 1. Detect Blue (Background)
    # Hue 90-130
    blue_mask = cv2.inRange(hsv, np.array([90, 30, 30]), np.array([130, 255, 255]))
    blue_ratio = cv2.countNonZero(blue_mask) / (img.shape[0] * img.shape[1])

    # 2. Detect Red (Plane)
    # Hue 0-10 or 170-179
    mask1 = cv2.inRange(hsv, np.array([0, 30, 30]), np.array([10, 255, 255]))
    mask2 = cv2.inRange(hsv, np.array([170, 30, 30]), np.array([179, 255, 255]))
    red_mask = mask1 + mask2
    red_ratio = cv2.countNonZero(red_mask) / (img.shape[0] * img.shape[1])

    # Also detect white/light areas (stamp borders/paper)
    white_mask = cv2.inRange(hsv, np.array([0, 0, 200]), np.array([180, 30, 255]))
    white_ratio = cv2.countNonZero(white_mask) / (img.shape[0] * img.shape[1])

    # 3. Filter Logic: Must have BOTH Blue and Red
    # Lowered thresholds to catch more candidates
    if blue_ratio > 0.02 and red_ratio > 0.01:
        matches.append((img_path, blue_ratio, red_ratio, white_ratio))
        print(
            f"   ✅ Match: {os.path.basename(img_path)} (Blue={blue_ratio:.2%}, Red={red_ratio:.2%}, White={white_ratio:.2%})"
        )

        # Save to a specific "Found" folder
        out_name = "STAMP_CANDIDATE_" + os.path.basename(img_path)
        cv2.imwrite(os.path.join(BASE_DIR, out_name), img)

# Print all candidates sorted by Blue+Red score
print("\n📊 All candidates ranked by Blue+Red score:")
all_scores = []
for img_path in candidates:
    img = cv2.imread(img_path)
    if img is None:
        continue
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    blue_mask = cv2.inRange(hsv, np.array([90, 30, 30]), np.array([130, 255, 255]))
    blue_ratio = cv2.countNonZero(blue_mask) / (img.shape[0] * img.shape[1])
    mask1 = cv2.inRange(hsv, np.array([0, 30, 30]), np.array([10, 255, 255]))
    mask2 = cv2.inRange(hsv, np.array([170, 30, 30]), np.array([179, 255, 255]))
    red_mask = mask1 + mask2
    red_ratio = cv2.countNonZero(red_mask) / (img.shape[0] * img.shape[1])
    white_mask = cv2.inRange(hsv, np.array([0, 0, 200]), np.array([180, 30, 255]))
    white_ratio = cv2.countNonZero(white_mask) / (img.shape[0] * img.shape[1])
    all_scores.append(
        (img_path, blue_ratio, red_ratio, white_ratio, blue_ratio + red_ratio)
    )

all_scores.sort(key=lambda x: x[4], reverse=True)
for img_path, blue_ratio, red_ratio, white_ratio, total in all_scores[:30]:
    print(
        f"   {os.path.basename(img_path)}: Blue={blue_ratio:.2%}, Red={red_ratio:.2%}, White={white_ratio:.2%}, Total={total:.2%}"
    )

# Refined filter: Look for balanced Blue+Red (stamp-like)
# Inverted Jenny: Blue border (~30-50%) + Red center (~20-40%)
# Also include some White/paper area

balanced_matches = []
for img_path, blue_ratio, red_ratio, white_ratio, total in all_scores:
    # Must have BOTH colors present (not 100% one color)
    if (
        blue_ratio >= 0.03
        and red_ratio >= 0.05
        and blue_ratio < 0.80
        and red_ratio < 0.90
    ):
        # Calculate balance: neither color should dominate > 85% of the total colored area
        if total > 0:
            blue_share = blue_ratio / total
            red_share = red_ratio / total
            # Good balance: both colors contribute meaningfully
            if blue_share >= 0.10 and red_share >= 0.15:
                balanced_matches.append(
                    (img_path, blue_ratio, red_ratio, white_ratio, total)
                )

print("\n🎯 Balanced Blue+Red candidates (stamp-like):")
balanced_matches.sort(key=lambda x: x[4], reverse=True)
for img_path, blue_ratio, red_ratio, white_ratio, total in balanced_matches[:20]:
    print(
        f"   {os.path.basename(img_path)}: Blue={blue_ratio:.2%}, Red={red_ratio:.2%}, White={white_ratio:.2%}"
    )
    img = cv2.imread(img_path)
    if img is not None:
        out_name = "BALANCED_STAMP_" + os.path.basename(img_path)
        cv2.imwrite(os.path.join(BASE_DIR, out_name), img)

print(f"\nFound {len(balanced_matches)} balanced candidates.")
