from pathlib import Path
from PIL import Image, ImageFilter
from collections import deque

ROOT = Path(__file__).resolve().parents[1]
web = ROOT / 'work' / 'assets' / 'web'
out = ROOT / 'work' / 'assets' / 'generated'
out.mkdir(parents=True, exist_ok=True)

src = web / 'p16_719A1022.jpg'
im = Image.open(src).convert('RGB')
# v06: crop closer to the actual product bbox while keeping full cup/saucer/package intact.
# The previous crop kept ~400px blank area above the product and cut too close to the bottom.
crop = im.crop((180, 680, 1220, 1430))
w, h = crop.size
pix = crop.load()
page_bg = (247, 246, 242)
corners = [pix[0, 0], pix[w - 1, 0], pix[0, h - 1], pix[w - 1, h - 1]]
bg = tuple(sum(c[i] for c in corners) // 4 for i in range(3))

def dist(c):
    return sum((c[i] - bg[i]) ** 2 for i in range(3)) ** 0.5

visited = bytearray(w * h)
mask = Image.new('L', (w, h), 0)
mp = mask.load()
q = deque()
for x in range(w):
    q.append((x, 0)); q.append((x, h - 1))
for y in range(h):
    q.append((0, y)); q.append((w - 1, y))
while q:
    x, y = q.popleft()
    if x < 0 or x >= w or y < 0 or y >= h:
        continue
    idx = y * w + x
    if visited[idx]:
        continue
    visited[idx] = 1
    r, g, b = pix[x, y]
    if dist((r, g, b)) <= 34 and min(r, g, b) > 210:
        mp[x, y] = 255
        q.append((x + 1, y)); q.append((x - 1, y)); q.append((x, y + 1)); q.append((x, y - 1))
soft = mask.filter(ImageFilter.GaussianBlur(2.0))
base = Image.new('RGB', (w, h), page_bg)
result = Image.composite(base, crop, soft)
out_path = out / 'closing_product_complete_v06.jpg'
result.save(out_path, quality=95)
print({'output': str(out_path), 'size': result.size, 'bg_sample': bg, 'mask_extrema': soft.getextrema()})
