create or replace function ems.fn_ev_session_apply_patch(
  p_site_id int,
  p_session_id int,
  p_patch jsonb
)
returns jsonb
language plpgsql
as $fn$
declare
  v_id int;
begin
  if not (p_patch ? 'target_soc_pct')
    and not (p_patch ? 'target_deadline')
    and not (p_patch ? 'soc_at_connect_pct')
    and not (p_patch ? 'opportunistic_value_czk_kwh') then
    return jsonb_build_object('success', false, 'error', 'no_fields');
  end if;

  if (p_patch ? 'opportunistic_value_czk_kwh')
    and jsonb_typeof(p_patch->'opportunistic_value_czk_kwh') <> 'null'
    and (p_patch->>'opportunistic_value_czk_kwh')::numeric < 0 then
    return jsonb_build_object(
      'success', false, 'error', 'opportunistic_value_negative'
    );
  end if;

  update ems.ev_session es
  set
    target_soc_pct = case
      when p_patch ? 'target_soc_pct' then
        case
          when p_patch->'target_soc_pct' is null
            or jsonb_typeof(p_patch->'target_soc_pct') = 'null' then null
          else (p_patch->>'target_soc_pct')::double precision
        end
      else es.target_soc_pct
    end,
    -- skutečné SoC při připojení (Tesla Fleet API po příjezdu)
    soc_at_connect_pct = case
      when p_patch ? 'soc_at_connect_pct' then
        case
          when p_patch->'soc_at_connect_pct' is null
            or jsonb_typeof(p_patch->'soc_at_connect_pct') = 'null' then null
          else (p_patch->>'soc_at_connect_pct')::double precision
        end
      else es.soc_at_connect_pct
    end,
    target_deadline = case
      when p_patch ? 'target_deadline' then
        case
          when p_patch->'target_deadline' is null
            or jsonb_typeof(p_patch->'target_deadline') = 'null' then null
          else (p_patch->>'target_deadline')::timestamptz
        end
      else es.target_deadline
    end,
    -- NULL = zdědit z asset_vehicle; 0 = oportunismus pro session vypnut
    opportunistic_value_czk_kwh = case
      when p_patch ? 'opportunistic_value_czk_kwh' then
        case
          when p_patch->'opportunistic_value_czk_kwh' is null
            or jsonb_typeof(p_patch->'opportunistic_value_czk_kwh') = 'null' then null
          else (p_patch->>'opportunistic_value_czk_kwh')::numeric
        end
      else es.opportunistic_value_czk_kwh
    end
  where es.id = p_session_id
    and es.site_id = p_site_id
  returning es.id into v_id;

  if v_id is null then
    return jsonb_build_object('success', false, 'session_id', null);
  end if;

  return jsonb_build_object('success', true, 'session_id', v_id);
end;
$fn$;

comment on function ems.fn_ev_session_apply_patch is
  'PATCH EV session – jen klíče přítomné v JSON (ISO string pro deadline; soc_at_connect_pct z Tesla API; opportunistic_value_czk_kwh >= 0, NULL = zdědit z vozidla, 0 = vypnout).';
