CREATE OR REPLACE FUNCTION get_service_ids_from_ropidgtfs_calendar(day_name character varying, start_date_ymd date)
    RETURNS TABLE(
        service_id character varying)
    LANGUAGE plpgsql
    AS $function$
BEGIN
    RETURN QUERY EXECUTE FORMAT('SELECT
            service_id
         FROM
            ropidgtfs_calendar
         WHERE
            %I = 1
            AND to_date(start_date, ''YYYYMMDD'') <= $1
            AND to_date(end_date, ''YYYYMMDD'') >= $1
         UNION
         SELECT
            service_id
         FROM
            ropidgtfs_calendar_dates
         WHERE
            exception_type = 1
            AND to_date(date, ''YYYYMMDD'') = $1
         EXCEPT
         SELECT
            service_id
         FROM
            ropidgtfs_calendar_dates
         WHERE
            exception_type = 2
            AND to_date(date, ''YYYYMMDD'') = $1', day_name)
    USING start_date_YMD;
END;
$function$;

COMMENT ON FUNCTION get_service_ids_from_ropidgtfs_calendar(varchar, date) IS 'Returns service_id values from ropidgtfs_calendar and ropidgtfs_calendar_dates for a specified day and date, accounting for exceptions.';

CREATE OR REPLACE FUNCTION normalize_departure_time(departure_time varchar(255))
    RETURNS character varying
    LANGUAGE plpgsql
    AS $function$
BEGIN
    RETURN CONCAT(mod(SUBSTRING(LPAD(departure_time, 8, '0'), 1, 2)::int, 24), SUBSTRING(LPAD(departure_time, 8, '0'), 3, 6));
END;
$function$;

COMMENT ON FUNCTION normalize_departure_time(varchar) IS 'Normalizes a departure_time string to a 24-hour format by wrapping the hour component (mod 24), ensuring the time remains valid, and preserves the minutes and seconds.';

CREATE OR REPLACE FUNCTION get_stop_ids_from_cis(startcisstopid integer, startaswstopid character varying, startcisstopplatformcode character varying)
    RETURNS character varying
    LANGUAGE plpgsql
    IMMUTABLE
    AS $function$
DECLARE
    result_string character varying;
BEGIN
    SELECT
        STRING_AGG(stop_id, ',') INTO result_string
    FROM
        ropidgtfs_stops
    WHERE
        stop_id LIKE (
            SELECT
                CONCAT('U', CAST(node AS text), 'Z%')
            FROM
                ropidgtfs_cis_stop_groups
            WHERE
                cis IN (
                    SELECT
                        cis
                    FROM
                        ropidgtfs_cis_stops
                    WHERE
                        cis = startCisStopId
                        OR id = startAswStopId))
            AND (platform_code LIKE startCisStopPlatformCode
                OR (LENGTH(platform_code) < 2
                    AND platform_code LIKE CAST((ASCII(startCisStopPlatformCode) - 64) AS char)));
    RETURN result_string;
END;
$function$;

COMMENT ON FUNCTION get_stop_ids_from_cis(integer, varchar, varchar) IS 'Fetches a stop_id from ropidgtfs_stops using CIS stop ID, ASW stop ID, and platform code, matching stop groups and filtering by platform code or alternatives.';

CREATE OR REPLACE FUNCTION is_within_12_hours(trip_date date, min_stop_time text, trip_start_timestamp timestamp with time zone)
    RETURNS boolean
    LANGUAGE plpgsql
    AS $function$
BEGIN
    RETURN abs(extract(epoch FROM((trip_date::timestamp AT TIME ZONE 'Europe/Prague' + min_stop_time::interval) - trip_start_timestamp))) < 43200;
END;
$function$;

COMMENT ON FUNCTION is_within_12_hours(date, text, timestamp with time zone) IS 'Checks if the difference between a trip''s start timestamp and the computed stop time(trip_date + min_stop_time) is less than 12 hours (43200 seconds).';

CREATE OR REPLACE FUNCTION match_trip_id(trip_id text, cis_trip_number integer)
    RETURNS boolean
    LANGUAGE plpgsql
    AS $function$
BEGIN
    RETURN trip_id ~ CONCAT('\d+_', cis_trip_number, '_\d+');
END;
$function$;

COMMENT ON FUNCTION match_trip_id(text, integer) IS 'Checks if the trip_id matches the pattern of "<digits>_<cis_trip_number>_<digits>"';

CREATE OR REPLACE FUNCTION get_wanted_trip(trip_id character varying)
    RETURNS TABLE(
        cis_line_short_name character varying,
        cis_trip_number integer,
        start_cis_stop_id integer,
        start_asw_stop_id character varying,
        start_timestamp timestamp with time zone,
        start_date date,
        start_date_name varchar,
        start_date_day_before date,
        start_date_day_before_name varchar)
    LANGUAGE plpgsql
    AS $function$
BEGIN
    RETURN QUERY
    SELECT
        vt.cis_line_short_name,
        vt.cis_trip_number,
        vt.start_cis_stop_id,
        vt.start_asw_stop_id,
        vt.start_timestamp,
        DATE_TRUNC('day', vt.start_timestamp)::date AS start_date,
        to_char(vt.start_timestamp, 'FMday')::varchar AS start_date_name,
(DATE_TRUNC('day', vt.start_timestamp) - INTERVAL '1 day')::date AS start_date_day_before,
        to_char(vt.start_timestamp - INTERVAL '1 day', 'FMday')::varchar AS start_date_day_before_name
    FROM
        vehiclepositions_trips vt
    WHERE
        id = trip_id
    LIMIT 1;
END;
$function$;

COMMENT ON FUNCTION get_wanted_trip(varchar) IS 'Retrieves detailed information about a trip from the vehiclepositions_trips table based on the given trip_id, including the start date and the previous day''s details.'
