-- pg_orrery 0.12.0 -> 0.13.0 migration
--
-- Adds: make_equatorial() constructor, rise/set prediction functions.
-- Nutation correction is integrated at the C level -- no SQL changes
-- needed for existing functions (their output values shift by ~arcseconds).

-- ============================================================
-- make_equatorial() constructor
-- ============================================================

CREATE FUNCTION make_equatorial(ra_hours float8, dec_deg float8, distance_km float8)
    RETURNS equatorial
    AS 'MODULE_PATHNAME', 'make_equatorial'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;

COMMENT ON FUNCTION make_equatorial(float8, float8, float8) IS
    'Construct equatorial from RA (hours [0,24)), Dec (degrees [-90,90]), distance (km).';


-- ============================================================
-- Rise/set prediction functions
-- ============================================================

-- Planets (geometric horizon)
CREATE FUNCTION planet_next_rise(body_id int4, obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION planet_next_rise(int4, observer, timestamptz) IS
    'Next geometric rise time for a planet. Returns NULL if no rise within 7 days. body_id: 1=Mercury..8=Neptune.';

CREATE FUNCTION planet_next_set(body_id int4, obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION planet_next_set(int4, observer, timestamptz) IS
    'Next geometric set time for a planet. Returns NULL if no set within 7 days. body_id: 1=Mercury..8=Neptune.';

-- Sun (geometric and refracted)
CREATE FUNCTION sun_next_rise(obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_next_rise(observer, timestamptz) IS
    'Next geometric sunrise. Returns NULL if Sun does not rise within 7 days (polar night).';

CREATE FUNCTION sun_next_set(obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_next_set(observer, timestamptz) IS
    'Next geometric sunset. Returns NULL if Sun does not set within 7 days (midnight sun).';

CREATE FUNCTION moon_next_rise(obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION moon_next_rise(observer, timestamptz) IS
    'Next geometric moonrise. Returns NULL if Moon does not rise within 7 days.';

CREATE FUNCTION moon_next_set(obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION moon_next_set(observer, timestamptz) IS
    'Next geometric moonset. Returns NULL if Moon does not set within 7 days.';

CREATE FUNCTION sun_next_rise_refracted(obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_next_rise_refracted(observer, timestamptz) IS
    'Next refracted sunrise (-0.833 deg threshold: refraction + semidiameter). Earlier than geometric by ~4 min.';

CREATE FUNCTION sun_next_set_refracted(obs observer, t timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME' LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_next_set_refracted(observer, timestamptz) IS
    'Next refracted sunset (-0.833 deg threshold: refraction + semidiameter). Later than geometric by ~4 min.';
