# FIXME: Refactor to daylight_range without Ts_start and Ts_end.


#' Constrain solar time range to daylight hours
#'
#' Adjusts the specified time range to only include periods when the sun is above the horizon.
#' Accounts for sunrise/sunset times and polar day/night conditions. Returns NULL if no sunlight
#' occurs during the specified period.
#'
#' @param Ls Areocentric longitude [deg]
#' @param phi Planetary latitude [deg]
#' @param Ts_start Start time to constrain [h]
#' @param Ts_end End time to constrain [h]
#' @param beta Surface tilt/slope angle from horizontal [deg]. Optional, for inclined surfaces
#' @param gamma_c Surface azimuth angle [deg]. Optional, for inclined surfaces
#'
#' @return List with Ts_start and Ts_end constrained to daylight hours, or NULL if no daylight
#' @noRd
constrain_solar_time_range = function(Ls, phi, Ts_start, Ts_end, beta=NULL, gamma_c=NULL){
  
  if(Ts_start >= Ts_end){
    stop("Solar start time cannot be after or equal to the solar end time.")
  }
  
  # If polar night.
  if(is_polar_night(Ls=Ls, phi=phi)){
    # No solar irradiance.
    return(NULL);
  }
  # If polar day.
  else if(is_polar_day(Ls=Ls, phi=phi)){
    # No constraining required: constant solar irradiance during polar day.
    # FIXME: What about for inclined surface?
    #        As in, what if the Sun is just above the horizon on the back of the inclined surface?
    return(
      list(Ts_start=Ts_start,
           Ts_end=Ts_end)
    )
  }
  # If non polar nights and non polar days.
  else{
    # Constrain Ts_start and Ts_end with respect to sunrise and sunset times.
    Tsr = sunrise(Ls=Ls, phi=phi, beta=beta, gamma_c=gamma_c, unit=3)
    Tss = sunset(Ls=Ls, phi=phi, beta=beta, gamma_c=gamma_c, unit=3)
    
    # In case there is no sunrise for the inclined surface.
    # e.g. high northern planetary latitude, oriented northwards.
    if(is.na(Tsr)){
      return(NULL)
    }
    
    # If start time is after the sunset, then there is no solar irradiance.
    else if(Ts_start > Tss){
      return(NULL)
    }
    # If end time is before the sunrise, then there is no solar irradiance.
    else if(Ts_end < Tsr){
      return(NULL)
      
    }else{
      # Be careful to cap the start hour angle to that of the sunrise hour angle.
      #   If you do not do this then you will calculate insolation for a 
      #   negative sunset hour angle, i.e. when the sun is below the horizon.
      if(Ts_start < Tsr){
        # Constrain the given solar time range to times after the sunrise time.
        Ts_start = Tsr
      }
      
      # Be careful to cap the end hour angle to that of the sunset hour angle.
      #   If you do not do this then you will calculate insolation for a 
      #   negative sunset hour angle, i.e. when the sun is below the horizon.
      if(Ts_end > Tss){
        # Constrain the given solar time range to time before to the sunset time.
        Ts_end = Tss
      }
    }
  }
  
  # When applying sunrise and sunset constraint has resulted in the start time being after or equal to the solar end time.
  if(Ts_start >= Ts_end){
    return(NULL)
  }
  
  # Return the contrained time range.
  return(
    list(Ts_start=Ts_start,
         Ts_end=Ts_end)
  )
}