from shortest_path import shortest_path
from graph import Graph
from PIL import Image
from PIL import ImageDraw


def generate_map_image(
    txt_filepath, output_filepath="dijkstra_map.jpg", path=None, scale=15
):
    """
    Reads the Dijkstra graph text file and generates a scaled JPG image.

    Args:
        txt_filepath (str): Path to the input .txt file.
        output_filepath (str): The name of the output .jpg file.
        path (list): List of nodes that will be marked in the output image.
        (should be used for the shortest path computed with dijkstra)
        scale (int): Multiplier to enlarge the image
    """
    pixel_data = {}

    with open(txt_filepath, 'r', encoding='utf-8') as file:
        lines = file.readlines()

    if not lines:
        print("Error: The file is empty.")
        return

    # 1. Parse Dimensions from the first line (e.g., "50x30")
    try:
        dim_str = lines[0].strip()
        width, height = map(int, dim_str.split("x"))
    except (ValueError, IndexError):
        print(
            "Error: Could not determine map dimensions from the first "
            "line of the file."
        )
        return

    # 2. Parse the remaining lines as coordinates
    for line in lines[1:]:
        line = line.strip()
        if not line:
            continue

        parts = line.split(",")
        if len(parts) >= 3:
            try:
                x = int(parts[0].strip())
                y = int(parts[1].strip())
                greyscale_val = int(parts[2].strip())
                pixel_data[(x, y)] = greyscale_val
            except ValueError:
                continue

    # Create a new Grayscale image ('L' mode in Pillow)
    img = Image.new('L', (width, height))
    pixels = img.load()

    # Apply the parsed greyscale values to the image pixels
    for (x, y), grey_val in pixel_data.items():
        pixels[x, y] = grey_val

    # Scale up the image so it is easy to view
    # Image.NEAREST is crucial here: it scales up without blurring grid lines
    if scale > 1:
        img = img.resize((width * scale, height * scale), Image.NEAREST)

    # Convert to RGB to support red color
    img = img.convert('RGB')

    # Draw red 'X' for each node/cell in the path
    if path:
        draw = ImageDraw.Draw(img)
        for (px, py) in path:
            x0 = px * scale
            y0 = py * scale
            x1 = (px + 1) * scale - 1
            y1 = (py + 1) * scale - 1
            # Draw diagonal lines
            draw.line([(x0, y0), (x1, y1)], fill=(255, 0, 0), width=1)
            draw.line([(x0, y1), (x1, y0)], fill=(255, 0, 0), width=1)

    # Save as JPG
    img.save(output_filepath)
    print(
        f"Success! Image saved as {output_filepath} "
        f"(Dimensions: {width * scale}x{height * scale})"
    )


def main():
    # test on the test graph
    g_test = Graph()
    g_test.construct_graph("dijkstra_greyscale_map_test.txt")
    path_test, distances_test = shortest_path(g_test, (2, 2), (47, 27))
    generate_map_image(
        "dijkstra_greyscale_map_test.txt",
        "visualized_map_test.jpg",
        path_test,
        scale=20
    )

    # uncomment the following to work the the actual graph

    g = Graph()
    g.construct_graph("dijkstra_greyscale_map_large.txt")
    path, distances = shortest_path(g, (0, 0), (59, 32))
    generate_map_image(
        "dijkstra_greyscale_map_large.txt",
        "visualized_map_large.jpg",
        path,
        scale=20
    )
    print(distances[(59, 32)])


if __name__ == "__main__":
    main()
