-- Lucozade Store Audit · Auth V6
-- Ejecutar una vez en Supabase SQL Editor.
-- Es idempotente y NO elimina usuarios de auth.users.
-- V6 usa los enlaces de recuperación nativos de Supabase Auth;
-- por eso elimina la tabla y los RPC personalizados de recuperación de V5.

begin;

-- Objetos obsoletos de V5 (ya no son necesarios).
drop function if exists public.lucozade_consume_password_reset(text, text);
drop function if exists public.lucozade_issue_password_reset(uuid, text);
drop function if exists public.lucozade_find_recoverable_user_by_email(text);
drop table if exists public.lucozade_password_reset_tokens;

-- Acceso específico a la aplicación.
create table if not exists public.lucozade_access (
  user_id uuid primary key references auth.users(id) on delete cascade,
  email text not null,
  full_name text,
  is_active boolean not null default true,
  created_at timestamptz not null default now(),
  updated_at timestamptz not null default now()
);

-- Compatibilidad si la tabla venía de una versión anterior.
alter table public.lucozade_access
  add column if not exists email text,
  add column if not exists full_name text,
  add column if not exists is_active boolean not null default true,
  add column if not exists created_at timestamptz not null default now(),
  add column if not exists updated_at timestamptz not null default now();

update public.lucozade_access
set email = lower(coalesce(email, ''))
where email is distinct from lower(coalesce(email, ''));

alter table public.lucozade_access
  alter column email set not null;

create index if not exists lucozade_access_email_idx
  on public.lucozade_access (lower(email));

create or replace function public.lucozade_set_updated_at()
returns trigger
language plpgsql
security invoker
set search_path = public
as $$
begin
  new.email = lower(trim(new.email));
  new.updated_at = now();
  return new;
end;
$$;

drop trigger if exists lucozade_access_set_updated_at on public.lucozade_access;
create trigger lucozade_access_set_updated_at
before update on public.lucozade_access
for each row execute function public.lucozade_set_updated_at();

-- Los usuarios creados por el workflow V6 llevan app_id=lucozade-audit.
-- Este trigger crea el acceso automáticamente; n8n también hace un upsert
-- como segunda garantía antes de responder que el registro terminó.
create or replace function public.handle_new_lucozade_user()
returns trigger
language plpgsql
security definer
set search_path = ''
as $$
begin
  if coalesce(new.raw_user_meta_data ->> 'app_id', '') = 'lucozade-audit' then
    insert into public.lucozade_access (
      user_id,
      email,
      full_name,
      is_active
    )
    values (
      new.id,
      lower(coalesce(new.email, '')),
      nullif(trim(coalesce(new.raw_user_meta_data ->> 'full_name', '')), ''),
      true
    )
    on conflict (user_id) do update
      set email = excluded.email,
          full_name = excluded.full_name,
          is_active = true,
          updated_at = now();
  end if;

  return new;
end;
$$;

drop trigger if exists on_lucozade_auth_user_created on auth.users;
create trigger on_lucozade_auth_user_created
after insert on auth.users
for each row execute function public.handle_new_lucozade_user();

-- Recupera accesos de usuarios Lucozade existentes que pudieran haber sido
-- creados antes de instalar el trigger.
insert into public.lucozade_access (
  user_id,
  email,
  full_name,
  is_active
)
select
  u.id,
  lower(coalesce(u.email, '')),
  nullif(trim(coalesce(u.raw_user_meta_data ->> 'full_name', '')), ''),
  true
from auth.users as u
where coalesce(u.raw_user_meta_data ->> 'app_id', '') = 'lucozade-audit'
  and coalesce(u.email, '') <> ''
on conflict (user_id) do update
  set email = excluded.email,
      full_name = coalesce(excluded.full_name, public.lucozade_access.full_name),
      updated_at = now();

alter table public.lucozade_access enable row level security;

drop policy if exists "Lucozade users can read their active access"
  on public.lucozade_access;

create policy "Lucozade users can read their active access"
on public.lucozade_access
for select
to authenticated
using (auth.uid() = user_id and is_active = true);

revoke all on public.lucozade_access from anon;
grant usage on schema public to authenticated, service_role;
grant select on public.lucozade_access to authenticated;
grant select, insert, update, delete on public.lucozade_access to service_role;

notify pgrst, 'reload schema';

commit;

-- IMPORTANTE:
-- Borrar una fila de public.lucozade_access revoca el acceso a Lucozade,
-- pero NO elimina la cuenta real de Supabase Auth.
-- Para eliminar totalmente una cuenta, use Authentication > Users
-- o, con extremo cuidado:
-- delete from auth.users where lower(email)=lower('correo@ejemplo.com');
