from math import ceil, log10
import os.path

from PIL import Image
import platformdirs

Image.MAX_IMAGE_PIXELS = 200000000
MAP_SIZE = 1024
DEFAULT_PATH = os.path.join(platformdirs.user_cache_dir(appname="lycacraft-paths", appauthor="Lycacraft"), "maps")


def clamp(mn, value, mx):
    return max(mn, min(mx, value))


def main():
    # src/utils/2024-06-27_21.01.45_Lycacraft_minecraft~overworld_day.png
    # 6144,10240
    input_path = input("Input image: ")
    output_path = input(f"Output dir (default: {DEFAULT_PATH}): ")
    if output_path.strip() == "":
        output_path = DEFAULT_PATH

    if not os.path.exists(output_path):
        os.makedirs(output_path)
    elif not os.path.isdir(output_path):
        print("Output path must be a directory")
        return

    center_pos = input("(0, 0) = ").split(",")
    cx, cy = list(map(lambda p: int(p), center_pos))
    image = Image.open(input_path)
    width, height = image.width, image.height

    left_maps = ceil(cx / MAP_SIZE)
    right_maps = ceil((width - cx) / MAP_SIZE)
    top_maps = ceil(cy / MAP_SIZE)
    bottom_maps = ceil((height - cy) / MAP_SIZE)
    h_maps = right_maps + left_maps
    v_maps = bottom_maps + top_maps

    total_maps = h_maps * v_maps
    digits = ceil(log10(total_maps - 1))
    map_i_str = f"{{:0{digits}d}}"
    print(f"{total_maps} maps will be created")
    proceed = input("Do you want to proceed ? y/[n] ")

    if proceed.lower().strip() != "y":
        return

    for y in range(v_maps):
        y0 = y * MAP_SIZE
        y1 = y0 + MAP_SIZE
        # y0 = clamp(0, y0, height)
        # y1 = clamp(0, y1, height)

        start_y = clamp(0, y0, height) - cy
        end_y = clamp(0, y1, height) - cy

        for x in range(h_maps):
            x0 = x * MAP_SIZE
            x1 = x0 + MAP_SIZE
            # x0 = clamp(0, x0, width)
            # x1 = clamp(0, x1, width)
            start_x = clamp(0, x0, width) - cx
            end_x = clamp(0, x1, width) - cx

            map_i = x + y * h_maps
            print(f"\r{map_i + 1}/{total_maps} ({map_i / total_maps * 100:.2f}%)", end="")
            map_image = image.crop((x0, y0, x1, y1))
            # map_image.save(
            #     os.path.join(
            #         output_path,
            #         f"map{map_i_str.format(map_i)}_{start_x},{start_y}_{end_x},{end_y}.png"
            #     )
            # )
            map_path = os.path.join(output_path, f"map{map_i_str.format(map_i)}_{x - left_maps}_{y - top_maps}.png")
            map_image.save(map_path)

    print(f"\r{total_maps}/{total_maps} (100%)")


if __name__ == '__main__':
    main()
