# app/utils/colorize.py
from pathlib import Path
from PIL import Image
import uuid
import re
from typing import Tuple

HEX_RE = re.compile(r"^#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$")

def _hex_to_rgba(hex_color: str, alpha: int = 255) -> Tuple[int, int, int, int]:
    m = HEX_RE.match(hex_color.strip())
    if not m:
        raise ValueError("Invalid hex color format")
    hex_str = m.group(1)
    if len(hex_str) == 3:
        r = int(hex_str[0]*2, 16)
        g = int(hex_str[1]*2, 16)
        b = int(hex_str[2]*2, 16)
    else:
        r = int(hex_str[0:2], 16)
        g = int(hex_str[2:4], 16)
        b = int(hex_str[4:6], 16)
    return (r, g, b, alpha)

def colorize_preview_with_mask(
    preview_path: str | Path,
    white_mask_path: str | Path,
    color_hex: str,
    output_dir: str | Path
) -> Path:
    """
    Create a colorized RGBA image where mask white pixels are replaced by the provided color.
    Returns path to saved PNG.
    """
    preview_path = Path(preview_path)
    white_mask_path = Path(white_mask_path)
    output_dir = Path(output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    rgba = Image.open(preview_path).convert("RGBA")
    mask = Image.open(white_mask_path).convert("L")

    # Resize mask to preview if needed
    if mask.size != rgba.size:
        mask = mask.resize(rgba.size, Image.Resampling.LANCZOS)

    color_rgba = _hex_to_rgba(color_hex)
    color_layer = Image.new("RGBA", rgba.size, color_rgba)

    # Composite: where mask is 255 -> take color_layer, else fallback to transparent
    # To keep preview content under colorization, we composite color only
    # Option A: color over preview (tint)
    # Here we create result where color is applied only where mask is white
    result = Image.new("RGBA", rgba.size, (0, 0, 0, 0))
    result.paste(color_layer, (0,0), mask)  # mask controls alpha of pasted color

    out_path = output_dir / f"{uuid.uuid4().hex}_colorized.png"
    result.save(out_path, format="PNG")
    return out_path
