-- Defaulty nové ev_session pro vozidlo: kaskáda
--   1) ems.ev_weekly_requirement — nejbližší budoucí výskyt enabled řádku
--      do 48 h od příjezdu (deadline_hour v den dow, Europe/Prague),
--   2) forecast z týdenního rytmu (V089: fn_ev_next_departure +
--      fn_ev_required_soc), jen při asset_vehicle.target_soc_forecast_enabled,
--   3) defaulty vozidla (default_target_soc_pct; deadline = příští výskyt
--      default_deadline_hour v Europe/Prague).
-- Volá fn_ev_session_transition při založení session; ruční přepis přes
-- fn_ev_session_apply_patch (Discord / UI) vždy vyhrává.

create or replace function ems.fn_ev_session_defaults(
  p_vehicle_id int,
  p_arrival timestamptz
)
returns jsonb
language plpgsql
stable
as $fn$
declare
  v_vehicle record;
  v_weekly record;
  v_forecast_departure timestamptz;
  v_deadline timestamptz;
begin
  select av.default_target_soc_pct, av.default_deadline_hour,
         av.target_soc_forecast_enabled
  into v_vehicle
  from ems.asset_vehicle av
  where av.id = p_vehicle_id;

  if not found then
    return jsonb_build_object(
      'target_soc_pct', null, 'deadline', null, 'source', 'none'
    );
  end if;

  -- 1) týdenní požadavek: nejbližší budoucí výskyt do 48 h (Europe/Prague)
  select wr.target_soc_pct, occ.deadline
  into v_weekly
  from generate_series(0, 2) as offs
  cross join lateral (
    select ((p_arrival at time zone 'Europe/Prague')::date + offs) as d
  ) day
  join ems.ev_weekly_requirement wr
    on wr.vehicle_id = p_vehicle_id
    and wr.enabled
    and wr.dow = extract(isodow from day.d)::int - 1
  cross join lateral (
    select (day.d::timestamp + make_interval(hours => wr.deadline_hour))
           at time zone 'Europe/Prague' as deadline
  ) occ
  where occ.deadline > p_arrival
    and occ.deadline <= p_arrival + interval '48 hours'
  order by occ.deadline
  limit 1;

  if v_weekly.deadline is not null then
    return jsonb_build_object(
      'target_soc_pct', v_weekly.target_soc_pct,
      'deadline', v_weekly.deadline,
      'source', 'weekly'
    );
  end if;

  -- 2) forecast z týdenního rytmu (chování shodné s dřívějším
  --    fn_ev_session_transition: deadline = typický odjezd; target P80,
  --    při málo datech default target)
  if v_vehicle.target_soc_forecast_enabled then
    v_forecast_departure := ems.fn_ev_next_departure(p_vehicle_id, p_arrival);
    if v_forecast_departure is not null then
      return jsonb_build_object(
        'target_soc_pct', coalesce(
          ems.fn_ev_required_soc(p_vehicle_id, v_forecast_departure),
          v_vehicle.default_target_soc_pct
        ),
        'deadline', v_forecast_departure,
        'source', 'forecast'
      );
    end if;
  end if;

  -- 3) defaulty vozidla: deadline = příští výskyt default_deadline_hour
  v_deadline := (
    (p_arrival at time zone 'Europe/Prague')::date::timestamp
    + make_interval(hours => v_vehicle.default_deadline_hour)
  ) at time zone 'Europe/Prague';
  if v_deadline <= p_arrival then
    v_deadline := (
      ((p_arrival at time zone 'Europe/Prague')::date + 1)::timestamp
      + make_interval(hours => v_vehicle.default_deadline_hour)
    ) at time zone 'Europe/Prague';
  end if;

  return jsonb_build_object(
    'target_soc_pct', v_vehicle.default_target_soc_pct,
    'deadline', v_deadline,
    'source', 'default'
  );
end;
$fn$;

comment on function ems.fn_ev_session_defaults is
'Target SoC + deadline pro novou ev_session: jsonb {target_soc_pct, deadline, source}. Kaskáda ev_weekly_requirement (výskyt do 48 h, Europe/Prague) → forecast (target_soc_forecast_enabled) → defaulty vozidla (deadline = příští výskyt default_deadline_hour). p_vehicle_id null/neznámé → null hodnoty.';
