-- User-turn origin for birth-time rectification.
-- Typed, choice, suggestion, voice, retry, and recovery writes must be
-- distinguishable when a later transcript contains a year the engine never
-- produced. Business schema only; do not copy into frontend/db/migrations
-- (BUG-127 / BUG-144).

begin;

alter table public.agentic_rectification_turns
  add column if not exists message_origin text;

alter table public.agentic_rectification_turns
  add column if not exists client_action_id uuid;

alter table public.agentic_rectification_turns
  add column if not exists content_hash text;

do $$
begin
  if not exists (
    select 1
    from pg_constraint
    where conname = 'agentic_rectification_turns_message_origin_check'
      and conrelid = 'public.agentic_rectification_turns'::regclass
  ) then
    alter table public.agentic_rectification_turns
      add constraint agentic_rectification_turns_message_origin_check
      check (
        message_origin is null
        or message_origin in (
          'typed',
          'suggestion_click',
          'choice_click',
          'voice_input',
          'retry_replay',
          'system_recovery'
        )
      );
  end if;
end;
$$;

create unique index if not exists agentic_rectification_turns_case_client_action_uidx
  on public.agentic_rectification_turns (case_id, client_action_id)
  where client_action_id is not null;

create or replace function public.record_agentic_rectification_turn_origin(
  p_user_id uuid,
  p_case_id uuid,
  p_turn_id uuid,
  p_origin text,
  p_client_action_id uuid,
  p_content_hash text
)
returns jsonb
language plpgsql
security definer
set search_path = ''
as $$
declare
  v_case public.agentic_rectification_cases%rowtype;
  v_turn public.agentic_rectification_turns%rowtype;
begin
  if p_user_id is null or p_case_id is null or p_turn_id is null
    or p_origin not in (
      'typed',
      'suggestion_click',
      'choice_click',
      'voice_input',
      'retry_replay',
      'system_recovery'
    ) then
    raise exception 'agentic_rectification_invalid_input' using errcode = 'P0001';
  end if;

  select * into v_case
  from public.agentic_rectification_cases
  where id = p_case_id and user_id = p_user_id
  for update;
  if not found then
    raise exception 'agentic_rectification_case_not_found' using errcode = 'P0001';
  end if;

  select * into v_turn
  from public.agentic_rectification_turns
  where id = p_turn_id and case_id = p_case_id
  for update;
  if not found then
    raise exception 'agentic_rectification_turn_not_found' using errcode = 'P0001';
  end if;

  if v_turn.message_origin is not null then
    if v_turn.message_origin is distinct from p_origin
      or v_turn.client_action_id is distinct from p_client_action_id
      or v_turn.content_hash is distinct from p_content_hash then
      raise exception 'agentic_rectification_request_mismatch' using errcode = 'P0001';
    end if;
    return jsonb_build_object(
      'turn_id', v_turn.id,
      'origin', v_turn.message_origin,
      'client_action_id', v_turn.client_action_id,
      'content_hash', v_turn.content_hash,
      'idempotent', true
    );
  end if;

  update public.agentic_rectification_turns
  set message_origin = p_origin,
      client_action_id = p_client_action_id,
      content_hash = p_content_hash,
      updated_at = pg_catalog.now()
  where id = p_turn_id;

  return jsonb_build_object(
    'turn_id', p_turn_id,
    'origin', p_origin,
    'client_action_id', p_client_action_id,
    'content_hash', p_content_hash,
    'idempotent', false
  );
end;
$$;

revoke all on function public.record_agentic_rectification_turn_origin(
  uuid, uuid, uuid, text, uuid, text
) from public, anon, authenticated;
grant execute on function public.record_agentic_rectification_turn_origin(
  uuid, uuid, uuid, text, uuid, text
) to service_role;

commit;
