-- migrate:up
--
-- Continuous day track for a vehicle: one GeoJSON LineString of every fix in
-- the EAT day, in time order. serve.fn_vehicle_trips returns each trip as its
-- own ST_MakeLine, so on the map a day with reporting-gap trip splits reads as
-- several disconnected segments. The frontend draws this track as a faint base
-- line under the coloured per-trip segments, so the route looks like one
-- continuous drive while individual trips stay highlighted.
--
-- EAT day boundary matches serve.fn_vehicle_trips (UTC+3). Light ST_Simplify
-- (~3 m) trims redundant points to keep the payload small without visibly
-- changing the shape. Returns NULL when there are fewer than 2 fixes.

CREATE OR REPLACE FUNCTION serve.fn_vehicle_day_track(
    p_vehicle_id bigint,
    p_date_eat   date
) RETURNS jsonb
LANGUAGE sql STABLE
AS $$
    WITH bounds AS (
        SELECT (p_date_eat::timestamp - interval '3 hours') AT TIME ZONE 'UTC' AS day_start
    ),
    -- Use one device's fixes (tracker-first, same canonical pick as
    -- fn_vehicle_trips) so a camera-paired vehicle's track doesn't zig-zag
    -- between the tracker and camera positions.
    primary_imei AS (
        SELECT d.imei
          FROM domain.devices d
         WHERE d.vehicle_id = p_vehicle_id
         ORDER BY CASE d.device_type WHEN 'tracker' THEN 0 ELSE 1 END, d.imei
         LIMIT 1
    ),
    pts AS (
        SELECT ph.geom, ph.occurred_at
          FROM state.position_history ph, bounds b, primary_imei pi
         WHERE ph.vehicle_id = p_vehicle_id
           AND ph.imei = pi.imei
           AND ph.occurred_at >= b.day_start
           AND ph.occurred_at <  b.day_start + interval '24 hours'
    )
    SELECT CASE
        WHEN count(*) >= 2
        THEN ST_AsGeoJSON(
                 ST_Simplify(ST_MakeLine(geom ORDER BY occurred_at), 0.00003)
             )::jsonb
        ELSE NULL
    END
      FROM pts;
$$;

-- migrate:down

DROP FUNCTION IF EXISTS serve.fn_vehicle_day_track(bigint, date);
