WITH raw AS (
    SELECT 
        Name,
        t_stamp,
        'Full' AS sig,
        Full AS val
    FROM lane_data
    WHERE t_stamp BETWEEN :startTime AND :endTime

    UNION ALL
    SELECT 
        Name,
        t_stamp,
        'Half_Full' AS sig,
        Half_Full AS val
    FROM lane_data
    WHERE t_stamp BETWEEN :startTime AND :endTime

    UNION ALL
    SELECT 
        Name,
        t_stamp,
        'Jam' AS sig,
        Jam AS val
    FROM lane_data
    WHERE t_stamp BETWEEN :startTime AND :endTime
),

-- ✨ Add artificial boundary rows so ongoing (val=1) states close at endTime
boundary AS (
    SELECT 
        Name,
        :endTime AS t_stamp,
        sig,
        0 AS val
    FROM raw
    GROUP BY Name, sig
),

ev AS (
    SELECT * FROM raw
    UNION ALL
    SELECT * FROM boundary
),

ordered AS (
    SELECT
        Name,
        sig,
        t_stamp,
        val,
        LAG(val) OVER (PARTITION BY Name, sig ORDER BY t_stamp) AS prev_val,
        LEAD(val) OVER (PARTITION BY Name, sig ORDER BY t_stamp) AS next_val,
        LEAD(t_stamp) OVER (PARTITION BY Name, sig ORDER BY t_stamp) AS next_ts
    FROM ev
),

intervals AS (
    SELECT
        Name,
        sig,
        TIMESTAMPDIFF(
            SECOND,
            t_stamp,
            next_ts
        ) AS duration_sec
    FROM ordered
    WHERE val = 1
),

dur AS (
    SELECT
        Name,
        SUM(CASE WHEN sig = 'Full' THEN duration_sec ELSE 0 END) AS Full_Duration_Sec,
        SUM(CASE WHEN sig = 'Half_Full' THEN duration_sec ELSE 0 END) AS Half_Full_Duration_Sec,
        SUM(CASE WHEN sig = 'Jam' THEN duration_sec ELSE 0 END) AS Jam_Duration_Sec
    FROM intervals
    GROUP BY Name
)

SELECT
    :startTime AS `Start Time`,
    :endTime AS `End Time`,
    d.Name AS `Lane ID`,
    COALESCE(d.Full_Duration_Sec, 0) AS `Full Duration (Sec)`,
    COALESCE(d.Half_Full_Duration_Sec, 0) AS `Half Full Duration (Sec)`,
    COALESCE(d.Jam_Duration_Sec, 0) AS `Jam Duration (Sec)`
FROM dur d

UNION ALL

SELECT
    :startTime,
    :endTime,
    'N/A',
    0,
    0,
    0
WHERE NOT EXISTS (SELECT 1 FROM dur)

ORDER BY `Lane ID`;
