create or replace function ems.fn_ev_arrival_prediction_bundle(p_site_id int) returns jsonb language plpgsql stable as $fn$ declare v_tz text; v_tomorrow date; v_n_sessions int; v_insufficient boolean; v_chargers jsonb := '{}'::jsonb; r record; v_rows jsonb; begin select coalesce(nullif(trim(s.timezone), ''), 'Europe/Prague') into v_tz from ems.site s where s.id = p_site_id; if not found then return jsonb_build_object('error', 'site_not_found'); end if; v_tomorrow := ( (current_timestamp at time zone v_tz)::date + 1 ); select count(*)::int into v_n_sessions from ems.ev_session where site_id = p_site_id; v_insufficient := coalesce(v_n_sessions, 0) < 5; for r in select id, code from ems.asset_ev_charger where site_id = p_site_id order by id loop select coalesce( jsonb_agg( jsonb_build_object( 'hour', x.expected_hour, 'confidence_pct', x.confidence_pct, 'samples', x.sample_count ) order by x.expected_hour ), '[]'::jsonb ) into v_rows from ems.fn_ev_expected_arrival(p_site_id, r.id, v_tomorrow) x; v_chargers := v_chargers || jsonb_build_object( r.code::text, jsonb_build_object('tomorrow', coalesce(v_rows, '[]'::jsonb)) ); end loop; return jsonb_build_object( 'insufficient_data', v_insufficient, 'tomorrow_date', v_tomorrow, 'chargers', v_chargers ); end; $fn$; comment on function ems.fn_ev_arrival_prediction_bundle(int) is 'Predikce příjezdů pro všechny nabíječky (nahrazuje N+1 volání fn_ev_expected_arrival).';