create table if not exists public.operations_stop_aliases (
  id text primary key default public.gen_hash_id() check (id ~ '^[0-9a-f]{16}$'),
  channel_id text not null references public.channels(id) on delete cascade,
  raw_stop_name text not null,
  raw_stop_name_normalized text generated always as (lower(btrim(raw_stop_name))) stored,
  alias_stop_name text not null,
  created_by uuid not null references auth.users(id) on delete restrict,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now(),
  constraint operations_stop_aliases_alias_not_blank check (char_length(btrim(alias_stop_name)) > 0),
  unique (channel_id, raw_stop_name_normalized)
);

create index if not exists idx_operations_stop_aliases_channel
  on public.operations_stop_aliases(channel_id);

alter table public.operations_stop_aliases enable row level security;

drop policy if exists "operations_stop_aliases_select_visible" on public.operations_stop_aliases;
create policy "operations_stop_aliases_select_visible"
  on public.operations_stop_aliases
  for select
  to authenticated
  using (public.can_access_channel(channel_id));

drop policy if exists "operations_stop_aliases_insert_admins" on public.operations_stop_aliases;
create policy "operations_stop_aliases_insert_admins"
  on public.operations_stop_aliases
  for insert
  to authenticated
  with check (
    created_by = auth.uid()
    and exists (
      select 1
      from public.channels c
      where c.id = channel_id
        and c.type = 'operations'
        and public.org_role(c.organization_id) in ('owner', 'admin')
    )
  );

drop policy if exists "operations_stop_aliases_update_admins" on public.operations_stop_aliases;
create policy "operations_stop_aliases_update_admins"
  on public.operations_stop_aliases
  for update
  to authenticated
  using (
    exists (
      select 1
      from public.channels c
      where c.id = channel_id
        and c.type = 'operations'
        and public.org_role(c.organization_id) in ('owner', 'admin')
    )
  )
  with check (
    exists (
      select 1
      from public.channels c
      where c.id = channel_id
        and c.type = 'operations'
        and public.org_role(c.organization_id) in ('owner', 'admin')
    )
  );

drop policy if exists "operations_stop_aliases_delete_admins" on public.operations_stop_aliases;
create policy "operations_stop_aliases_delete_admins"
  on public.operations_stop_aliases
  for delete
  to authenticated
  using (
    exists (
      select 1
      from public.channels c
      where c.id = channel_id
        and c.type = 'operations'
        and public.org_role(c.organization_id) in ('owner', 'admin')
    )
  );

drop trigger if exists trg_operations_stop_aliases_updated_at on public.operations_stop_aliases;
create trigger trg_operations_stop_aliases_updated_at
before update on public.operations_stop_aliases
for each row execute procedure public.tg_set_updated_at();
