"""
Convert two-theta to q, and perform forward/inverse Fourier transforms.
"""

import numpy as np
from scipy.constants import physical_constants

CLASSICAL_ELECTRON_RADIUS_ANGSTROM = (
    physical_constants["classical electron radius"][0] * 1e10
)


def tth2q(tth, wavelength):
    """
    q = 4π sin(θ/2) / λ, with θ in degrees.
    """
    return 4 * np.pi * np.sin(np.deg2rad(tth / 2)) / wavelength


def IFT_slow(sqrtRq4, q, zrange):
    """
    Discrete inverse FT of sqrt(R q^4):
    returns d_rho (complex) vs z, with z spanning ±zrange/2.
    """
    z = np.linspace(-zrange / 2, zrange / 2, len(q))
    pref = 4 * np.pi * CLASSICAL_ELECTRON_RADIUS_ANGSTROM
    dq = (q.max() - q.min()) / len(q)
    M = np.exp(-1j * np.outer(q, z))
    intensity = M * (sqrtRq4 / pref)[:, None]
    d_rho = -np.trapezoid(intensity, dx=dq, axis=0) / np.pi
    return d_rho, z


def DFT_slow(d_rho, z, qmin, qmax):
    """
    Discrete forward FT to compute sqrt(R q^4) from d_rho(z).
    """
    q = np.linspace(qmin, qmax, len(z))
    pref = 4 * np.pi * CLASSICAL_ELECTRON_RADIUS_ANGSTROM
    dz = (z.max() - z.min()) / len(z)
    M = np.exp(1j * np.outer(q, z))
    FT = M * d_rho[None, :] * pref
    sqrtRq4 = np.trapezoid(FT, dx=dz, axis=1)
    return sqrtRq4, q
