-- ============================================================================
-- TABLERO CDC — PERMISO INDIVIDUAL PARA "HORAS DEL EQUIPO"
-- Migración aditiva y segura.
--
-- Objetivo:
--   1) Agregar tablero_cdc_allowed_users.can_view_team_hours.
--   2) Mantener el acceso actual de los usuarios activos existentes la primera vez.
--   3) Dejar nuevos usuarios SIN este permiso por defecto.
--   4) Proteger los RPC usados por el módulo Horas del equipo.
--
-- No modifica proyectos, horas, histórico, métricas, tarifarios, listas ni briefs.
-- ============================================================================

begin;

-- Se ejecuta de forma idempotente. Solo en la PRIMERA instalación del permiso
-- se conserva el comportamiento actual dando acceso a los usuarios activos existentes.
do $$
declare
  permission_was_missing boolean;
begin
  select not exists (
    select 1
    from information_schema.columns
    where table_schema = 'public'
      and table_name = 'tablero_cdc_allowed_users'
      and column_name = 'can_view_team_hours'
  ) into permission_was_missing;

  if permission_was_missing then
    alter table public.tablero_cdc_allowed_users
      add column can_view_team_hours boolean not null default false;

    update public.tablero_cdc_allowed_users
    set can_view_team_hours = true,
        updated_at = now()
    where is_active = true;
  end if;
end
$$;

comment on column public.tablero_cdc_allowed_users.can_view_team_hours is
  'Controla si el usuario puede ver y consultar el módulo Horas del equipo. Los usuarios nuevos quedan sin acceso hasta que se les habilite explícitamente.';

-- Función central de permiso. Se usa desde el frontend y desde los RPC de datos.
create or replace function public.tablero_cdc_current_user_can_view_team_hours()
returns boolean
language sql
stable
security definer
set search_path = public
as $$
  select exists (
    select 1
    from public.tablero_cdc_allowed_users u
    where lower(trim(u.email)) = lower(trim(coalesce(auth.jwt() ->> 'email', '')))
      and u.is_active = true
      and u.can_view_team_hours = true
  );
$$;

revoke all on function public.tablero_cdc_current_user_can_view_team_hours() from public;
grant execute on function public.tablero_cdc_current_user_can_view_team_hours() to authenticated;

-- Roster de equipo: solo usuarios con el permiso pueden consultarlo.
create or replace function public.tablero_cdc_get_team_hours_roster()
returns table (
  email text,
  full_name text
)
language plpgsql
stable
security definer
set search_path = public
as $$
begin
  if not public.tablero_cdc_current_user_can_view_team_hours() then
    raise exception 'No autorizado';
  end if;

  return query
  select
    lower(trim(u.email)) as email,
    coalesce(nullif(trim(u.full_name), ''), lower(trim(u.email))) as full_name
  from public.tablero_cdc_allowed_users u
  where u.is_active = true
  order by coalesce(nullif(trim(u.full_name), ''), lower(trim(u.email)));
end;
$$;

revoke all on function public.tablero_cdc_get_team_hours_roster() from public;
grant execute on function public.tablero_cdc_get_team_hours_roster() to authenticated;

-- Lectura paginada de horas actuales + histórico. El acceso se valida en servidor,
-- de modo que ocultar el botón no sea el único control del módulo.
create or replace function public.tablero_cdc_get_team_hours_records(
  p_from date default null,
  p_to date default null,
  p_limit integer default 1000,
  p_offset integer default 0
)
returns table (
  id uuid,
  record_source text,
  source_key text,
  work_date date,
  project_name text,
  client text,
  country text,
  worked_by_name text,
  worked_by_email text,
  task_name text,
  duration_minutes integer,
  notes text
)
language plpgsql
stable
security definer
set search_path = public
as $$
begin
  if not public.tablero_cdc_current_user_can_view_team_hours() then
    raise exception 'No autorizado';
  end if;

  return query
  select
    c.id,
    c.record_source,
    c.source_key,
    c.work_date,
    c.project_name,
    c.client,
    c.country,
    c.worked_by_name,
    c.worked_by_email,
    c.task_name,
    c.duration_minutes,
    c.notes
  from public.tablero_cdc_time_combined c
  where (p_from is null or c.work_date >= p_from)
    and (p_to is null or c.work_date <= p_to)
  order by c.work_date desc, c.id asc
  limit least(greatest(coalesce(p_limit, 1000), 1), 1000)
  offset greatest(coalesce(p_offset, 0), 0);
end;
$$;

revoke all on function public.tablero_cdc_get_team_hours_records(date, date, integer, integer) from public;
grant execute on function public.tablero_cdc_get_team_hours_records(date, date, integer, integer) to authenticated;

commit;

-- ============================================================================
-- ADMINISTRACIÓN DEL PERMISO
-- ============================================================================
-- Dar acceso:
-- update public.tablero_cdc_allowed_users
-- set can_view_team_hours = true, updated_at = now()
-- where lower(email) = lower('correo@gomezleemarketing.com');
--
-- Quitar acceso:
-- update public.tablero_cdc_allowed_users
-- set can_view_team_hours = false, updated_at = now()
-- where lower(email) = lower('correo@gomezleemarketing.com');
--
-- Ver estado actual:
select
  email,
  full_name,
  role,
  is_active,
  can_view_team_hours
from public.tablero_cdc_allowed_users
order by full_name nulls last, email;
