-- =========================================================
-- pacientesIndexPage.sql
-- Views + índices para a tela PatientsListPage
-- =========================================================

-- 0) Extensões úteis
create extension if not exists pg_trgm;

-- 1) updated_at automático (se você quiser manter updated_at sempre correto)
create or replace function public.set_updated_at()
returns trigger
language plpgsql
as $$
begin
  new.updated_at = now();
  return new;
end;
$$;

drop trigger if exists trg_patients_set_updated_at on public.patients;
create trigger trg_patients_set_updated_at
before update on public.patients
for each row execute function public.set_updated_at();


-- =========================================================
-- 2) Views de contagem (usadas em KPIs e telas auxiliares)
-- =========================================================

-- 2.1) Grupos com contagem de pacientes
create or replace view public.v_patient_groups_with_counts as
select
  g.id,
  g.name,
  g.color,
  coalesce(count(pgp.patient_id), 0)::int as patients_count
from public.patient_groups g
left join public.patient_group_patient pgp
  on pgp.patient_group_id = g.id
group by g.id, g.name, g.color;

-- 2.2) Tags com contagem de pacientes
create or replace view public.v_tag_patient_counts as
select
  t.id,
  t.name,
  t.color,
  coalesce(count(ppt.patient_id), 0)::int as patients_count
from public.patient_tags t
left join public.patient_patient_tag ppt
  on ppt.tag_id = t.id
group by t.id, t.name, t.color;


-- =========================================================
-- 3) View principal da Index (pacientes + grupos/tags agregados)
-- =========================================================

create or replace view public.v_patients_index as
select
  p.*,

  -- array JSON com os grupos do paciente
  coalesce(gx.groups, '[]'::jsonb) as groups,

  -- array JSON com as tags do paciente
  coalesce(tx.tags, '[]'::jsonb) as tags,

  -- contagens para UI/KPIs
  coalesce(gx.groups_count, 0)::int as groups_count,
  coalesce(tx.tags_count, 0)::int as tags_count

from public.patients p

left join lateral (
  select
    jsonb_agg(
      distinct jsonb_build_object(
        'id', g.id,
        'name', g.name,
        'color', g.color
      )
    ) filter (where g.id is not null) as groups,
    count(distinct g.id) as groups_count
  from public.patient_group_patient pgp
  join public.patient_groups g
    on g.id = pgp.patient_group_id
  where pgp.patient_id = p.id
) gx on true

left join lateral (
  select
    jsonb_agg(
      distinct jsonb_build_object(
        'id', t.id,
        'name', t.name,
        'color', t.color
      )
    ) filter (where t.id is not null) as tags,
    count(distinct t.id) as tags_count
  from public.patient_patient_tag ppt
  join public.patient_tags t
    on t.id = ppt.tag_id
  where ppt.patient_id = p.id
) tx on true;


-- =========================================================
-- 4) Índices recomendados (performance real na listagem/filtros)
-- =========================================================

-- Patients
create index if not exists idx_patients_owner_id
  on public.patients (owner_id);

create index if not exists idx_patients_created_at
  on public.patients (created_at desc);

create index if not exists idx_patients_status
  on public.patients (status);

create index if not exists idx_patients_last_attended_at
  on public.patients (last_attended_at desc);

-- Busca rápida (name/email/phone)
create index if not exists idx_patients_name_trgm
  on public.patients using gin (name gin_trgm_ops);

create index if not exists idx_patients_email_trgm
  on public.patients using gin (email gin_trgm_ops);

create index if not exists idx_patients_phone_trgm
  on public.patients using gin (phone gin_trgm_ops);

-- Pivot: grupos
create index if not exists idx_pgp_patient_id
  on public.patient_group_patient (patient_id);

create index if not exists idx_pgp_group_id
  on public.patient_group_patient (patient_group_id);

-- Pivot: tags
create index if not exists idx_ppt_patient_id
  on public.patient_patient_tag (patient_id);

create index if not exists idx_ppt_tag_id
  on public.patient_patient_tag (tag_id);
