import requests
import os
import json
from PIL import Image
from tqdm import tqdm

# You change these:
# ====================
PAGE_NAME = "my_page_1"
ID = "https://dlcs.bl.digirati.io/iiif-img/v3/2/3/81055___vdc_100165767239.0x00008d"
# ====================

URL = ID + "/{},{},{},{}/{},{}/0/default.jpg"
INFO_URL = ID + "/info.json"


def strip_extension(filename: str) -> str:
    """Return filename without its extension."""
    return os.path.splitext(filename)[0]


def download_image(region_x, region_y, region_w, region_h, w, h):
	filename = f"{region_x}-{region_y}-{region_w}-{region_h}-{w}-{h}.jpg"
	if not os.path.isfile(filename):
		response = requests.get(URL.format(region_x, region_y, region_w, region_h, w, h))

		if response.status_code == 200:
			with open(filename, "wb") as file:
				file.write(response.content)
		else:
			print(f"<<< Failed to download '{filename}': {response.text} >>>")
			print(response.url)


def download_image_fullres(region_x, region_y, w, h):
	download_image(region_x, region_y, w, h, w, h)


# Get page info

print("Getting page info...")
response = requests.get(INFO_URL)
if response.status_code != 200:
	print("Failed to get page info:", response.text)
	exit()
info = json.loads(response.text)

full_width  = info["width"]
full_height = info["height"]

width_blocks, width_remainder   = divmod(full_width, 512)
height_blocks, height_remainder = divmod(full_height, 512)

print("=== Page Info ===")
print(f"Resolution:    {full_width}x{full_height}")
print(f"Width  Blocks: {width_blocks}, Remainder: {width_remainder}")
print(f"Height Blocks: {height_blocks}, Remainder: {height_remainder}")
print("=================")
total_images      = (width_blocks + 1) * (height_blocks + 1)
download_progress = tqdm(total=total_images, desc="Downloading tiles", unit="tile")

# ===== Download step =====

os.makedirs(PAGE_NAME, exist_ok=True)
os.chdir(PAGE_NAME)

# Download full tiles
for row_i in range(0, height_blocks):
	for column_i in range(0, width_blocks):
		pos_x = column_i * 512
		pos_y = row_i * 512
		download_image_fullres(pos_x, pos_y, 512, 512)
		download_progress.update(1)

# Download width remainder tiles (excludes bottom row)
for row_i in range(0, height_blocks):
	pos_x = width_blocks * 512
	pos_y = row_i * 512
	download_image_fullres(pos_x, pos_y, width_remainder, 512)
	download_progress.update(1)

# Download height remainder tiles (except bottom right corner)
for column_i in range(0, width_blocks):
	pos_x = column_i * 512
	pos_y = height_blocks * 512
	download_image_fullres(pos_x, pos_y, 512, height_remainder)
	download_progress.update(1)

# Bottom right corner
pos_x = width_blocks * 512
pos_y = height_blocks * 512
download_image_fullres(pos_x, pos_y, width_remainder, height_remainder)
download_progress.update(1)
download_progress.close()

# ===== Merge step =====

stitch_progress = tqdm(total=total_images, desc="Merging tiles", unit="tile")

canvas = Image.new("RGB", (full_width, full_height))

for file_or_dir in os.listdir():
	if os.path.isfile(file_or_dir) and file_or_dir.endswith(".jpg") and not file_or_dir.startswith("output"):
		filename = file_or_dir
		tile = Image.open(filename)
		region_x, region_y, region_w, region_h, w, h = strip_extension(filename).split("-")
		canvas.paste(tile, (int(region_x), int(region_y)))
		stitch_progress.update(1)
stitch_progress.close()

print("Saving...")
canvas.save("output.jpg")

print("Saved as output.jpg")

