from pathlib import Path

import cv2
import numpy as np


ROOT = Path("/home/vela/workspace/domain/tn-silver/web/tn-site")
SOURCE_IMAGE = Path("/home/vela/Music/temp6.png")
RUNTIME = ROOT / ".runtime/image-edit-temp6"
OUTPUT = ROOT / "output/imagegen/temp6-ring"
MUSIC = Path("/home/vela/Music")

CROP_X = 900
CROP_Y = 300
CROP_W = 420
CROP_H = 400

# Centers of the new index-finger ring in each 420 x 400 API edit.
SOURCE_CENTERS = {
    "01": (182, 179),
    "02": (217, 198),
    "03": (204, 200),
    "04": (195, 199),
    "05": (199, 200),
    "06": (198, 185),
    "07": (192, 205),
    "08": (198, 169),
}

# A common physically plausible placement on the original index finger.
DESTINATION_CENTER = (189, 198)

# The mask is intentionally tight: enough for the ring and its contact shadow,
# but too small to replace the surrounding hand or face.
MASK_AXES = {
    "01": (14, 17),
    "02": (15, 19),
    "03": (16, 20),
    "04": (14, 19),
    "05": (15, 19),
    "06": (16, 20),
    "07": (15, 19),
    "08": (16, 19),
}


def load_image(path: Path) -> np.ndarray:
    image = cv2.imread(str(path), cv2.IMREAD_COLOR)
    if image is None:
        raise RuntimeError(f"Could not read image: {path}")
    return image


def main() -> None:
    full = load_image(SOURCE_IMAGE)
    if full.shape[:2] != (992, 1586):
        raise RuntimeError(f"Unexpected source dimensions: {full.shape[1]}x{full.shape[0]}")

    original_crop = full[CROP_Y : CROP_Y + CROP_H, CROP_X : CROP_X + CROP_W].copy()
    composite_dir = RUNTIME / "poisson-composites"
    composite_dir.mkdir(parents=True, exist_ok=True)
    OUTPUT.mkdir(parents=True, exist_ok=True)

    patch_size = 52
    patch_half = patch_size // 2

    for variant, (source_x, source_y) in SOURCE_CENTERS.items():
        source = load_image(RUNTIME / f"api-edits/variant-{variant}-420.png")
        if source.shape[:2] != (CROP_H, CROP_W):
            raise RuntimeError(
                f"Unexpected dimensions for variant {variant}: "
                f"{source.shape[1]}x{source.shape[0]}"
            )

        x0 = source_x - patch_half
        y0 = source_y - patch_half
        patch = source[y0 : y0 + patch_size, x0 : x0 + patch_size].copy()
        if patch.shape[:2] != (patch_size, patch_size):
            raise RuntimeError(f"Variant {variant} patch extends beyond the source")

        mask = np.zeros((patch_size, patch_size), dtype=np.uint8)
        cv2.ellipse(
            mask,
            (patch_half, patch_half),
            MASK_AXES[variant],
            0,
            0,
            360,
            255,
            thickness=-1,
            lineType=cv2.LINE_AA,
        )

        blended_crop = cv2.seamlessClone(
            patch,
            original_crop,
            mask,
            DESTINATION_CENTER,
            cv2.MIXED_CLONE,
        )
        cv2.imwrite(str(composite_dir / f"hand-variant-{variant}.png"), blended_crop)

        composited_full = full.copy()
        composited_full[
            CROP_Y : CROP_Y + CROP_H,
            CROP_X : CROP_X + CROP_W,
        ] = blended_crop

        output_path = OUTPUT / f"temp6-index-ring-v{variant}.png"
        music_path = MUSIC / output_path.name
        cv2.imwrite(str(output_path), composited_full)
        cv2.imwrite(str(music_path), composited_full)


if __name__ == "__main__":
    main()
