-- Only render message history that was captured verbatim at answer time.
-- Evidence rows created before the history contract contain normalized event
-- summaries, not guaranteed user-authored chat text, so they must not be used
-- to reconstruct a conversation.

alter table public.birth_time_rectification_turns
  add column if not exists user_message_captured boolean not null default false;

create or replace function public.load_conversational_rectification_case_with_history(
  p_user_id uuid,
  p_case_id uuid default null
)
returns jsonb
language plpgsql
stable
security definer
set search_path = ''
as $$
declare
  v_loaded jsonb;
  v_case_id uuid;
begin
  v_loaded := public.load_conversational_rectification_case(p_user_id, p_case_id);
  if v_loaded is null then
    return null;
  end if;
  v_case_id := (v_loaded ->> 'case_id')::uuid;
  return v_loaded || pg_catalog.jsonb_build_object(
    'message_history', coalesce((
      select pg_catalog.jsonb_agg(
        pg_catalog.jsonb_build_object(
          'turnVersion', turn_row.turn_version,
          'userMessage', turn_row.user_message,
          'narrative', turn_row.narrative
        ) order by turn_row.turn_version
      )
      from (
        select history.turn_version, history.user_message, history.narrative
        from public.birth_time_rectification_turns history
        where history.case_id = v_case_id
          and history.user_message_captured is true
        order by history.turn_version desc
        limit 200
      ) turn_row
    ), '[]'::jsonb)
  );
end;
$$;

create or replace function public.save_conversational_rectification_turn_with_history(
  p_user_id uuid,
  p_case_id uuid,
  p_expected_version bigint,
  p_action_id uuid,
  p_turn jsonb,
  p_evidence jsonb,
  p_validation_receipt jsonb,
  p_private_candidate jsonb,
  p_command_fingerprint text,
  p_user_message text
)
returns jsonb
language plpgsql
security definer
set search_path = ''
as $$
declare
  v_response jsonb;
  v_saved_user_message text;
begin
  if p_user_message is null
    or public.conversational_rectification_text_utf16_length(p_user_message) not between 1 and 4000
    or public.conversational_rectification_text_is_nonblank(p_user_message) is not true then
    raise exception 'conversational_action_conflict' using errcode = 'P0001';
  end if;
  v_response := public.save_conversational_rectification_turn(
    p_user_id, p_case_id, p_expected_version, p_action_id, p_turn, p_evidence,
    p_validation_receipt, p_private_candidate, p_command_fingerprint
  );
  update public.birth_time_rectification_turns
  set user_message = coalesce(user_message, p_user_message),
      user_message_captured = true
  where case_id = p_case_id
    and turn_version = p_expected_version + 1
  returning user_message into v_saved_user_message;
  if not found or v_saved_user_message is distinct from p_user_message then
    raise exception 'conversational_action_conflict' using errcode = 'P0001';
  end if;
  return v_response;
end;
$$;

create or replace function public.complete_conversational_rectification_with_range_and_history(
  p_user_id uuid,
  p_case_id uuid,
  p_expected_version bigint,
  p_action_id uuid,
  p_turn jsonb,
  p_evidence jsonb,
  p_validation_receipt jsonb,
  p_private_candidate jsonb,
  p_command_fingerprint text,
  p_user_message text
)
returns jsonb
language plpgsql
security definer
set search_path = ''
as $$
declare
  v_response jsonb;
  v_saved_user_message text;
begin
  if p_user_message is null
    or public.conversational_rectification_text_utf16_length(p_user_message) not between 1 and 4000
    or public.conversational_rectification_text_is_nonblank(p_user_message) is not true then
    raise exception 'conversational_action_conflict' using errcode = 'P0001';
  end if;
  v_response := public.complete_conversational_rectification_with_range(
    p_user_id, p_case_id, p_expected_version, p_action_id, p_turn, p_evidence,
    p_validation_receipt, p_private_candidate, p_command_fingerprint
  );
  update public.birth_time_rectification_turns
  set user_message = coalesce(user_message, p_user_message),
      user_message_captured = true
  where case_id = p_case_id
    and turn_version = p_expected_version + 1
  returning user_message into v_saved_user_message;
  if not found or v_saved_user_message is distinct from p_user_message then
    raise exception 'conversational_action_conflict' using errcode = 'P0001';
  end if;
  return v_response;
end;
$$;

revoke all on function public.load_conversational_rectification_case_with_history(uuid, uuid)
  from public, anon, authenticated;
revoke all on function public.save_conversational_rectification_turn_with_history(
  uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) from public, anon, authenticated;
revoke all on function public.complete_conversational_rectification_with_range_and_history(
  uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) from public, anon, authenticated;

grant execute on function public.load_conversational_rectification_case_with_history(uuid, uuid)
  to service_role;
grant execute on function public.save_conversational_rectification_turn_with_history(
  uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) to service_role;
grant execute on function public.complete_conversational_rectification_with_range_and_history(
  uuid, uuid, bigint, uuid, jsonb, jsonb, jsonb, jsonb, text, text
) to service_role;
