"""
Preprocessing steps: dark-current correction, monitor normalization,
direct-beam amplitude fitting, footprint correction, background handling.
"""

import numpy as np


def correct_dark(mon, dark_current, itime):
    """
    Subtract dark current: mon - dark_current * itime.
    """
    return mon - dark_current * itime


def norm_monitor(det, mon_corr):
    """
    Divide detector counts by corrected monitor.
    """
    return det / mon_corr


def fit_direct_beam(tth, detm):
    """
    Estimate direct-beam amplitude as the value of detm closest to 0.
    """
    index = np.abs(tth).argmin()
    return detm[index]


def footprint_correction(theta_in, beam_size, sample_length):
    """
    Compute footprint correction factor:
      θ_o = arcsin(beam_size / sample_length)
    For θ_in < θ_o:  sin(rad(θ_in)) / (beam_size/length)
    Else: 1.
    """
    from numpy import arcsin, sin, rad2deg, deg2rad

    θo = rad2deg(arcsin(beam_size / sample_length))
    mask = theta_in < θo
    fpc = np.where(
        mask, np.abs(sin(deg2rad(theta_in)) / (beam_size / sample_length)), 1.0
    )
    return fpc


def subtract_bg(signal, bg):
    """
    Simple subtraction: signal - bg.
    """
    return signal - bg
