-- ============================================================
-- Gustito Xpress — FLUJO DE MESA DEL MESERO (fase 1: modelo de datos).
--
-- Amplia el modelo de mesa para la logica de trabajo del mesero:
--   * cuentas_mesa: cuantas personas (comensales) y si la cuenta va
--     JUNTA o SEPARADA (modo_cuenta).
--   * comensales_mesa: las personas de una cuenta (registro real, para
--     ver que pide cada quien). Un pedido se amarra a una persona.
--   * llamadas_mesa: el cliente llama al mesero o pide la cuenta; el
--     mesero asignado recibe el aviso (trigger de push en fase 2/3).
--
-- Todo es ADITIVO: no rompe cuentas_mesa ni pagos_mesa existentes.
-- El anti-cruce (una cuenta activa por mesa) NO se toca.
-- ============================================================

-- ---- cuentas_mesa: comensales + modo de cuenta ----
alter table public.cuentas_mesa
  add column if not exists comensales int not null default 1 check (comensales >= 1);
alter table public.cuentas_mesa
  add column if not exists modo_cuenta text not null default 'unica' check (modo_cuenta in ('unica','separada'));

-- ---- comensales_mesa: las personas de una cuenta ----
create table if not exists public.comensales_mesa (
  id             uuid primary key default gen_random_uuid(),
  cuenta_id      uuid not null references public.cuentas_mesa(id) on delete cascade,
  restaurante_id uuid not null references public.restaurantes(id) on delete cascade,
  nombre         text not null,
  orden          int not null default 0,
  creado_en      timestamptz not null default now()
);
create index if not exists idx_comensales_mesa_cuenta on public.comensales_mesa (cuenta_id, orden);
alter table public.comensales_mesa enable row level security;

-- Staff/dueño del restaurante administran a los comensales de sus cuentas.
-- El cliente los ve por la RPC cuenta_mesa (security definer), no directo.
drop policy if exists comensales_mesa_staff_all on public.comensales_mesa;
create policy comensales_mesa_staff_all on public.comensales_mesa
  for all to authenticated
  using (fn_es_staff_de(restaurante_id) or fn_es_admin())
  with check (fn_es_staff_de(restaurante_id) or fn_es_admin());

-- ---- pedidos.comensal_id: a que persona pertenece el pedido ----
-- OJO: el esquema inicial YA traia pedidos.comensal_id apuntando a perfiles
-- (concepto viejo de "comensal" = perfil, sin uso). Por eso un simple
-- "add column if not exists" no crea el FK correcto. Lo repuntamos a
-- comensales_mesa, que es el registro real de personas de la mesa.
alter table public.pedidos add column if not exists comensal_id uuid;
alter table public.pedidos drop constraint if exists pedidos_comensal_id_fkey;
alter table public.pedidos
  add constraint pedidos_comensal_id_fkey foreign key (comensal_id)
  references public.comensales_mesa(id) on delete set null;
create index if not exists idx_pedidos_comensal on public.pedidos (comensal_id) where (comensal_id is not null);

-- ---- llamadas_mesa: el cliente llama al mesero / pide la cuenta ----
create table if not exists public.llamadas_mesa (
  id             uuid primary key default gen_random_uuid(),
  cuenta_id      uuid not null references public.cuentas_mesa(id) on delete cascade,
  restaurante_id uuid not null references public.restaurantes(id) on delete cascade,
  mesa           text not null,
  tipo           text not null check (tipo in ('mesero','cuenta')),
  nota           text,
  creada_en      timestamptz not null default now(),
  atendida_en    timestamptz,
  atendida_por   uuid references public.perfiles(id) on delete set null
);
-- Una sola llamada PENDIENTE por cuenta+tipo (evita spam de toques del cliente).
create unique index if not exists uq_llamada_pendiente
  on public.llamadas_mesa (cuenta_id, tipo) where (atendida_en is null);
create index if not exists idx_llamadas_rest_pend
  on public.llamadas_mesa (restaurante_id) where (atendida_en is null);
alter table public.llamadas_mesa enable row level security;

-- Staff VE y ATIENDE las llamadas de su restaurante. Se CREA solo via RPC
-- llamar_mesero (el cliente es anon), por eso no hay policy de insert.
drop policy if exists llamadas_mesa_staff_select on public.llamadas_mesa;
create policy llamadas_mesa_staff_select on public.llamadas_mesa
  for select to authenticated
  using (fn_es_staff_de(restaurante_id) or fn_es_admin());
drop policy if exists llamadas_mesa_staff_update on public.llamadas_mesa;
create policy llamadas_mesa_staff_update on public.llamadas_mesa
  for update to authenticated
  using (fn_es_staff_de(restaurante_id) or fn_es_admin())
  with check (fn_es_staff_de(restaurante_id) or fn_es_admin());
