package utils

import (
	"time"

	"github.com/sixdouglas/suncalc"
)

// AstronomicalData contains calculated astronomical data for a recording
type AstronomicalData struct {
	SolarNight bool    // True if recording midpoint is between sunset and sunrise
	CivilNight bool    // True if recording midpoint is between dusk and dawn (6° below horizon)
	MoonPhase  float64 // 0.00=New Moon, 0.25=First Quarter, 0.50=Full Moon, 0.75=Last Quarter
}

// CalculateAstronomicalData calculates astronomical data for a recording.
// Uses the recording MIDPOINT time (not start time) for calculations.
//
// Parameters:
//   - timestampUTC: Recording start time in UTC
//   - durationSec: Recording duration in seconds
//   - lat, lon: Location coordinates in decimal degrees
//
// Returns:
//   - solarNight: true if recording midpoint is between sunset and sunrise
//   - civilNight: true if recording midpoint is between dusk and dawn
//   - moonPhase: 0.00-1.00 representing moon phase (0=New, 0.5=Full)
func CalculateAstronomicalData(
	timestampUTC time.Time,
	durationSec float64,
	lat, lon float64,
) AstronomicalData {
	// Calculate recording MIDPOINT (not start time)
	midpoint := timestampUTC.Add(time.Duration(durationSec/2) * time.Second)

	// Get solar times for midpoint date
	times := suncalc.GetTimes(midpoint, lat, lon)

	// Solar night: between sunset and sunrise
	// Note: Handle day/night transitions properly
	sunrise := times[suncalc.Sunrise].Value
	sunset := times[suncalc.Sunset].Value
	solarNight := isBetweenSunTimes(midpoint, sunset, sunrise)

	// Civil night: between dusk and dawn (6° below horizon)
	dawn := times[suncalc.Dawn].Value
	dusk := times[suncalc.Dusk].Value
	civilNight := isBetweenSunTimes(midpoint, dusk, dawn)

	// Moon phase: 0.00=New Moon, 0.25=First Quarter, 0.50=Full Moon, 0.75=Last Quarter
	moonIllum := suncalc.GetMoonIllumination(midpoint)
	moonPhase := moonIllum.Phase

	return AstronomicalData{
		SolarNight: solarNight,
		CivilNight: civilNight,
		MoonPhase:  moonPhase,
	}
}

// isBetweenSunTimes determines if a time is between sunset/dusk and sunrise/dawn
// Handles the case where the night period crosses midnight
func isBetweenSunTimes(t, evening, morning time.Time) bool {
	// If evening time is before morning time (normal case: both on same day)
	// Then we're NOT in night period (daytime)
	if evening.Before(morning) {
		return false
	}

	// Otherwise, night period crosses midnight
	// Night is: after evening OR before morning
	return t.After(evening) || t.Before(morning)
}

// CalculateMidpointTime calculates the midpoint time of a recording
func CalculateMidpointTime(startTime time.Time, durationSec float64) time.Time {
	return startTime.Add(time.Duration(durationSec/2) * time.Second)
}