#!/usr/bin/env python3
"""
Tatiana's pixel-perfect patch composite.
Places FF logo as an embroidered patch on the astronaut's lit arm.
"""

from PIL import Image, ImageDraw, ImageFilter
import numpy as np

# Load images
base = Image.open("v1-03-mid-full-body.png").convert("RGBA")
logo_raw = Image.open("ff-logo-mark.png").convert("RGBA")

print(f"Base: {base.size}")
print(f"Logo raw: {logo_raw.size}")

# --- Build the patch ---

# Patch dimensions (small, real-looking)
PATCH_W = 90
PATCH_H = 75
LOGO_MARGIN = 10  # margin inside patch for logo

# Resize logo to fit inside patch with margin
logo_area_w = PATCH_W - 2 * LOGO_MARGIN
logo_area_h = PATCH_H - 2 * LOGO_MARGIN
logo_raw.thumbnail((logo_area_w, logo_area_h), Image.LANCZOS)
logo_resized = logo_raw

print(f"Logo resized: {logo_resized.size}")

# Create patch canvas (off-white fabric color)
patch_color = (238, 232, 220, 255)  # warm off-white
patch = Image.new("RGBA", (PATCH_W, PATCH_H), patch_color)

# Process logo: white→transparent, dark pixels→dark embroidery color
logo_data = np.array(logo_resized)
# Embroidery thread color (dark charcoal, slightly textured feel)
emb_color = np.array([22, 18, 12], dtype=np.uint8)

# Create mask: pixels that are "dark" (logo mark)
# Logo is RGBA - use alpha + darkness
r, g, b, a = logo_data[:,:,0], logo_data[:,:,1], logo_data[:,:,2], logo_data[:,:,3]
darkness = (r.astype(int) + g.astype(int) + b.astype(int)) / 3
# Where it's dark AND has alpha: logo pixels
is_logo = (darkness < 128) & (a > 50)

# Build logo overlay
logo_overlay = np.zeros((logo_resized.height, logo_resized.width, 4), dtype=np.uint8)
logo_overlay[is_logo] = [emb_color[0], emb_color[1], emb_color[2], 230]  # slight translucency for embroidery feel

logo_img = Image.fromarray(logo_overlay, "RGBA")

# Center logo on patch
lx = (PATCH_W - logo_resized.width) // 2
ly = (PATCH_H - logo_resized.height) // 2
patch.paste(logo_img, (lx, ly), logo_img)

# Draw stitched border
draw = ImageDraw.Draw(patch)
border_color = (180, 170, 155, 255)  # slightly darker than patch, thread color
stitch_gap = 4  # pixels between stitches
stitch_len = 4  # length of each stitch dash

# Top border stitches
for x in range(3, PATCH_W - 3, stitch_gap + stitch_len):
    draw.line([(x, 3), (min(x + stitch_len, PATCH_W - 3), 3)], fill=border_color, width=1)
# Bottom border stitches
for x in range(3, PATCH_W - 3, stitch_gap + stitch_len):
    draw.line([(x, PATCH_H - 4), (min(x + stitch_len, PATCH_W - 3), PATCH_H - 4)], fill=border_color, width=1)
# Left border stitches
for y in range(3, PATCH_H - 3, stitch_gap + stitch_len):
    draw.line([(3, y), (3, min(y + stitch_len, PATCH_H - 3))], fill=border_color, width=1)
# Right border stitches
for y in range(3, PATCH_H - 3, stitch_gap + stitch_len):
    draw.line([(PATCH_W - 4, y), (PATCH_W - 4, min(y + stitch_len, PATCH_H - 3))], fill=border_color, width=1)

# Outer border rectangle (solid, thin)
draw.rectangle([1, 1, PATCH_W - 2, PATCH_H - 2], outline=(160, 150, 135, 255), width=1)

# --- Sample suit color at target location for color matching ---
# Patch placement on the lit right arm area
# The task specifies x=875-950, y=700-820 for the bright lit arm
PASTE_X = 878
PASTE_Y = 710

# Slightly tint patch to match local arm color (warm suit tones)
# Sample the arm area
base_rgb = base.convert("RGB")
arm_sample = base_rgb.crop((PASTE_X, PASTE_Y, PASTE_X + PATCH_W, PASTE_Y + PATCH_H))
arm_pixels = np.array(arm_sample)
avg_arm = arm_pixels.mean(axis=(0, 1))
print(f"Average arm color at placement: R={avg_arm[0]:.0f} G={avg_arm[1]:.0f} B={avg_arm[2]:.0f}")

# Create shadow/edge effect under patch (makes it look physically placed)
shadow_size = 3
patch_with_shadow = Image.new("RGBA", (PATCH_W + shadow_size * 2, PATCH_H + shadow_size * 2), (0, 0, 0, 0))
# Shadow layer
shadow = Image.new("RGBA", (PATCH_W, PATCH_H), (0, 0, 0, 60))
patch_with_shadow.paste(shadow, (shadow_size + 1, shadow_size + 1), shadow)
# Patch on top
patch_with_shadow.paste(patch, (shadow_size, shadow_size), patch)

# Slight blur on shadow only - we'll composite carefully
# Use a simple approach: paste patch directly at position with shadow offset

# --- Paste onto base ---
base_copy = base.copy()

# First paste shadow
shadow_layer = Image.new("RGBA", base.size, (0, 0, 0, 0))
shadow_patch = Image.new("RGBA", (PATCH_W, PATCH_H), (0, 0, 0, 45))
# Slight blur for soft shadow
shadow_patch_blurred = shadow_patch.filter(ImageFilter.GaussianBlur(2))
shadow_layer.paste(shadow_patch_blurred, (PASTE_X + 2, PASTE_Y + 2), shadow_patch_blurred)
base_copy = Image.alpha_composite(base_copy, shadow_layer)

# Then paste patch (no alpha compositing - solid placement)
patch_layer = Image.new("RGBA", base.size, (0, 0, 0, 0))
patch_layer.paste(patch, (PASTE_X, PASTE_Y), patch)
base_copy = Image.alpha_composite(base_copy, patch_layer)

# Save as JPEG
result = base_copy.convert("RGB")
result.save("tatiana-patch-v2.jpg", quality=95)
print(f"Saved: tatiana-patch-v2.jpg ({result.size})")

# Also save a debug crop to verify placement
debug_crop = result.crop((PASTE_X - 50, PASTE_Y - 50, PASTE_X + PATCH_W + 50, PASTE_Y + PATCH_H + 50))
debug_crop.save("tatiana-patch-v2-debug.jpg", quality=95)
print(f"Saved debug crop: tatiana-patch-v2-debug.jpg")
