import math

import numpy as np

DEFAULT_TRANSITION_RADIUS_BY_ZOOM = {
    2: 3.0,
    4: 4.0,
    6: 6.0,
    8: 10.0,
}


def detect_boundary(mask):
    boundary = np.zeros(mask.shape, dtype=bool)
    boundary[1:, :] |= mask[1:, :] != mask[:-1, :]
    boundary[:-1, :] |= mask[:-1, :] != mask[1:, :]
    boundary[:, 1:] |= mask[:, 1:] != mask[:, :-1]
    boundary[:, :-1] |= mask[:, :-1] != mask[:, 1:]
    return boundary


def chamfer_distance(boundary):
    height, width = boundary.shape
    inf = np.float32(1e9)
    dist = np.full((height, width), inf, dtype=np.float32)
    dist[boundary] = 0.0

    sqrt2 = np.float32(math.sqrt(2.0))

    for row in range(height):
        for col in range(width):
            current = dist[row, col]
            if row > 0:
                current = min(current, dist[row - 1, col] + 1.0)
                if col > 0:
                    current = min(current, dist[row - 1, col - 1] + sqrt2)
                if col + 1 < width:
                    current = min(current, dist[row - 1, col + 1] + sqrt2)
            if col > 0:
                current = min(current, dist[row, col - 1] + 1.0)
            dist[row, col] = current

    for row in range(height - 1, -1, -1):
        for col in range(width - 1, -1, -1):
            current = dist[row, col]
            if row + 1 < height:
                current = min(current, dist[row + 1, col] + 1.0)
                if col > 0:
                    current = min(current, dist[row + 1, col - 1] + sqrt2)
                if col + 1 < width:
                    current = min(current, dist[row + 1, col + 1] + sqrt2)
            if col + 1 < width:
                current = min(current, dist[row, col + 1] + 1.0)
            dist[row, col] = current

    return dist


def build_coast_transition_band(land_mask, radius_pixels):
    if radius_pixels <= 0:
        return np.zeros(land_mask.shape, dtype=np.float32)

    boundary = detect_boundary(land_mask)
    if not np.any(boundary):
        return np.zeros(land_mask.shape, dtype=np.float32)

    distance = chamfer_distance(boundary)
    band = 1.0 - distance / float(radius_pixels)
    return np.clip(band, 0.0, 1.0).astype(np.float32)
