"""Boundary data utilities for harmonic measure computation."""

from __future__ import annotations

import numpy as np
from numpy.typing import NDArray


def sigmoid(t: float | NDArray) -> float | NDArray:
    """Standard sigmoid function σ(t) = 1 / (1 + e^{-t})."""
    return 1.0 / (1.0 + np.exp(-np.clip(t, -500, 500)))


def smooth_indicator(inside: bool, delta: float = 0.1) -> float:
    """Convert boolean to smooth indicator value.

    Returns ~1 if inside, ~0 if not, with transition width delta.
    """
    return sigmoid((1.0 if inside else -1.0) / delta)


def smooth_corner_indicator(
    pts: NDArray[np.floating],
    corners: list[tuple[float, float]],
    radius: float,
    delta: float | None = None,
) -> NDArray[np.floating]:
    """Smooth indicator for corner neighborhoods.

    g(ξ) = σ((ρ - d(ξ)) / δ)

    where d(ξ) is distance to nearest corner.

    Parameters
    ----------
    pts : ndarray, shape (N, 2)
        Boundary points
    corners : list of (x, y)
        Corner locations
    radius : float
        Neighborhood radius ρ
    delta : float, optional
        Smoothing width (default: radius/5)

    Returns
    -------
    g : ndarray, shape (N,)
        Smooth indicator values
    """
    if delta is None:
        delta = radius / 5.0

    corners = np.array(corners)
    n = pts.shape[0]
    g = np.zeros(n)

    for i in range(n):
        # Distance to nearest corner
        dists = np.sqrt(np.sum((corners - pts[i]) ** 2, axis=1))
        d = np.min(dists)

        # Smooth indicator
        g[i] = sigmoid((radius - d) / delta)

    return g


def corner_boundary_data(
    pts: NDArray[np.floating],
    a: float,
    rho: float,
    delta: float | None = None,
) -> NDArray[np.floating]:
    """Standard corner indicator for Lamé curves.

    Corners are at (±1, ±a).

    Parameters
    ----------
    pts : ndarray, shape (N, 2)
        Boundary points
    a : float
        Aspect ratio (y semi-axis)
    rho : float
        Corner neighborhood radius
    delta : float, optional
        Smoothing width

    Returns
    -------
    g : ndarray, shape (N,)
        Boundary data values
    """
    corners = [(1, a), (1, -a), (-1, a), (-1, -a)]
    return smooth_corner_indicator(pts, corners, rho, delta)
