CREATE OR REPLACE FUNCTION ems.fn_update_ev_arrival_stats(
    p_site_id    INT,
    p_charger_id INT,
    p_vehicle_id INT,
    p_arrived_at TIMESTAMPTZ
)
RETURNS VOID
LANGUAGE sql
AS $$
  INSERT INTO ems.ev_arrival_stats
      (site_id, charger_id, vehicle_id, day_of_week, arrival_hour, sample_count, last_updated)
  VALUES (
      p_site_id,
      p_charger_id,
      p_vehicle_id,
      EXTRACT(DOW FROM p_arrived_at AT TIME ZONE 'Europe/Prague')::INT,
      EXTRACT(HOUR FROM p_arrived_at AT TIME ZONE 'Europe/Prague')::INT,
      1,
      now()
  )
  ON CONFLICT (site_id, charger_id, day_of_week, arrival_hour) DO UPDATE SET
      sample_count = ems.ev_arrival_stats.sample_count + 1,
      last_updated = now();
$$;

COMMENT ON FUNCTION ems.fn_update_ev_arrival_stats(INT, INT, INT, TIMESTAMPTZ) IS
'Přidá jeden příjezd do statistiky. Volat při otevření nové EV session
(telemetry_collector: přechod status available → preparing/charging).';


CREATE OR REPLACE FUNCTION ems.fn_ev_expected_arrival(
    p_site_id    INT,
    p_charger_id INT,
    p_for_date   DATE DEFAULT (
        (CURRENT_TIMESTAMP AT TIME ZONE 'Europe/Prague')::date + 1
    )
)
RETURNS TABLE (
    expected_hour  INT,
    confidence_pct INT,
    sample_count   INT
)
LANGUAGE sql
STABLE
AS $$
  SELECT
      s.arrival_hour,
      ROUND(
          s.sample_count::NUMERIC
          / NULLIF(SUM(s.sample_count) OVER (PARTITION BY s.day_of_week), 0)
          * 100
      )::INT,
      s.sample_count
  FROM ems.ev_arrival_stats s
  WHERE s.site_id = p_site_id
    AND s.charger_id = p_charger_id
    AND s.day_of_week = EXTRACT(DOW FROM p_for_date)::INT
    AND s.sample_count >= 2
  ORDER BY s.sample_count DESC
  LIMIT 3;
$$;

COMMENT ON FUNCTION ems.fn_ev_expected_arrival(INT, INT, DATE) IS
'Top 3 nejčastější hodiny příjezdu EV pro den v týdnu odpovídající kalendářnímu datu p_for_date.
Backend předává „zítřek“ v časové zóně lokality. Použití: notifikace, později solver.';
