from aceti.map_utils import import_map, MapDownloader
import numpy as np
import matplotlib.pyplot as plt
import PIL

def plot_grid(map):
    ''' Plot a grid on top of a map. '''

    #check map properties
    if isinstance(map, str):
        base_matrix, lat_lon_map  = import_map(map)
    elif isinstance(map, tuple):
        base_matrix, lat_lon_map  = map
        if isinstance(base_matrix, np.ndarray) and isinstance(lat_lon_map, np.ndarray):
            if not np.all(np.isin(base_matrix, [0, 1])):
                raise ValueError("base_matrix must be a numpy array of 0s and 1s")
            if base_matrix.shape != lat_lon_map.shape:
                raise ValueError("base_matrix and lat_lon_map must have the same shape")
            if not np.all(np.apply_along_axis(lambda x: isinstance(x, tuple) and len(x) == 2 and all(isinstance(i, float) for i in x), 1, lat_lon_map)):
                raise ValueError("lat_lon_map must be a numpy array of tuples of 2 coordinates, [lat, lon]")
        else:
            raise ValueError("map must be a string or a tuple of [base_matrix, lat_lon_map]")
    else:
        raise ValueError("map must be a string or a tuple of [base_matrix, lat_lon_map]")
    # Plot the map
    print("lat_lon_map shape: ", lat_lon_map.shape)
    print("base_matrix shape: ", base_matrix.shape)
    print("lat_lon_map: ", lat_lon_map[0, 0])
    print("lat_lon_map: ", lat_lon_map[-1, -1])
    #to tuple
    northwest = [float(lat_lon_map[0, 0][0]), float(lat_lon_map[0, 0][1])]
    southeast = [float(lat_lon_map[-1, -1][0]), float(lat_lon_map[-1, -1][1])]
    map=MapDownloader(northwest, southeast, zoom=19, layer="s", server ="arcgis") 
    map.generateImage()
    # map.raw_map_img = PIL.Image.open("AlamilloPlantilla.png")
    # plt.imshow(map.map_img)
    # plt.savefig("alamillo95x216.png", dpi=600)
    map.show_grid(lat_lon_map, base_matrix)

    # plt.figure()
    # plt.imshow(base_matrix, cmap='gray', interpolation='nearest')
    # plt.show()

def save_as_csv():
    base_matrix, lat_lon_map  = import_map("/home/aloepacci/guadaira")

    # Ensure base_matrix is integer 0/1
    base_matrix = base_matrix.astype(int)

    # If lat_lon_map is an object array of tuples convert to numeric shape (nrows,ncols,2)
    # Normalize lat_lon_map to numeric shape (nrows, ncols, 2) with dtype float64
    if lat_lon_map.dtype == object:
        h, w = lat_lon_map.shape[:2]
        converted = np.zeros((h, w, 2), dtype=np.float64)
        for i in range(h):
            for j in range(w):
                v = lat_lon_map[i, j]
                if v is None:
                    converted[i, j, :] = np.nan
                else:
                    # Support (lat, lon) tuples or lists
                    converted[i, j, 0] = float(v[0])
                    converted[i, j, 1] = float(v[1])
        lat_lon_map = converted
    else:
        # if already numeric, ensure shape is (h,w,2)
        if lat_lon_map.ndim == 3 and lat_lon_map.shape[2] == 2:
            lat_lon_map = lat_lon_map.astype(np.float64)
        elif lat_lon_map.ndim == 2 and lat_lon_map.shape[1] == 2:
            # already flattened 2-col array, try to infer h,w from base_matrix
            try:
                h, w = base_matrix.shape
                lat_lon_map = lat_lon_map.reshape((h, w, 2)).astype(np.float64)
            except Exception:
                lat_lon_map = lat_lon_map.astype(np.float64)

    # Save base matrix as integer CSV
    np.savetxt("guadairaplantilla.csv", base_matrix, delimiter=" ", fmt='%d')

    # Save lat/lon grid with the same 2D shape as base_matrix: each cell is "lat,lon"
    h, w = base_matrix.shape
    if lat_lon_map.shape[0] != h or lat_lon_map.shape[1] != w:
        # try to reshape if lat_lon_map is flattened
        try:
            lat_lon_map = lat_lon_map.reshape((h, w, 2))
        except Exception:
            raise ValueError(f"lat_lon_map shape {lat_lon_map.shape} incompatible with base_matrix shape {base_matrix.shape}")

    str_grid = np.empty((h, w), dtype=object)
    for i in range(h):
        for j in range(w):
            lat = lat_lon_map[i, j, 0]
            lon = lat_lon_map[i, j, 1]
            # Format: lat,lon with 6 decimals
            str_grid[i, j] = f"{lat:.6f},{lon:.6f}"

    np.savetxt("guadairagrid.csv", str_grid, delimiter=";", fmt='%s')


# csv_to_npy("alamillo95x216")
# csv_to_png("alamillo95x216plantilla")

# plot_grid("alamilloaccess11x15")
# plot_grid("alamillo95x216")

# plot_grid("/home/aloepacci/guadaira")
# plot_grid("alamillo30x49")
# map=MapDownloader([37.191611287951396, -4.399097018031518], [37.188098777474906, -4.394347328263865], zoom=19, layer="s", server ="arcgis")
# map=MapDownloader([37.341664356846564, -5.858012026866486], [37.33741741302848, -5.855613536856963], zoom=19, layer="s", server ="arcgis")
# map.save_navigation_waters(name="guadaira")

# plt.imshow(map.map_img)
# plt.axis('off')
# plt.savefig("guadaira.png", dpi=600)


import matplotlib.pyplot as plt
base_matrix, lat_lon_map  = import_map("/home/aloepacci/trabajo/aceti/guadaira84")

base_matrix = base_matrix.T
plt.imshow(base_matrix, cmap='gray', interpolation='nearest')
plt.axis('off')
plt.gca().spines['top'].set_visible(False)
plt.gca().spines['right'].set_visible(False)
plt.gca().spines['left'].set_visible(False)
plt.gca().spines['bottom'].set_visible(False)
#quita todos los bordes en la imagen savefig
plt.savefig("guadaira_mask.png", dpi=600, bbox_inches='tight', pad_inches=0)
plt.show()