-- =====================================================
-- Module Notification Rules & Queue
-- Shared notification infrastructure for courses, events, bookings.
-- =====================================================

-- Notification rules: define what triggers notifications
CREATE TABLE IF NOT EXISTS public.module_notification_rules (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  account_id uuid NOT NULL REFERENCES public.accounts(id) ON DELETE CASCADE,
  module text NOT NULL CHECK (module IN ('courses', 'events', 'bookings')),
  trigger_event text NOT NULL CHECK (trigger_event IN (
    'course.participant_enrolled', 'course.participant_waitlisted', 'course.participant_promoted',
    'course.participant_cancelled', 'course.status_changed', 'course.session_reminder',
    'event.registration_confirmed', 'event.registration_waitlisted', 'event.registration_promoted',
    'event.registration_cancelled', 'event.status_changed', 'event.reminder',
    'booking.confirmed', 'booking.check_in_reminder', 'booking.checked_in',
    'booking.checked_out', 'booking.cancelled'
  )),
  channel text NOT NULL DEFAULT 'in_app' CHECK (channel IN ('in_app', 'email', 'both')),
  recipient_type text NOT NULL DEFAULT 'admin' CHECK (recipient_type IN ('admin', 'participant', 'guest', 'instructor', 'specific_user')),
  recipient_config jsonb NOT NULL DEFAULT '{}',
  subject_template text,
  message_template text NOT NULL,
  is_active boolean NOT NULL DEFAULT true,
  created_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS ix_module_notification_rules_lookup
  ON public.module_notification_rules(account_id, module, trigger_event)
  WHERE is_active = true;

ALTER TABLE public.module_notification_rules ENABLE ROW LEVEL SECURITY;
REVOKE ALL ON public.module_notification_rules FROM authenticated, service_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON public.module_notification_rules TO authenticated;
GRANT ALL ON public.module_notification_rules TO service_role;

CREATE POLICY module_notification_rules_select ON public.module_notification_rules
  FOR SELECT TO authenticated USING (public.has_role_on_account(account_id));

CREATE POLICY module_notification_rules_mutate ON public.module_notification_rules
  FOR ALL TO authenticated USING (
    public.has_permission(auth.uid(), account_id, 'settings.manage'::public.app_permissions)
  ) WITH CHECK (
    public.has_permission(auth.uid(), account_id, 'settings.manage'::public.app_permissions)
  );

-- Pending notifications queue
CREATE TABLE IF NOT EXISTS public.pending_module_notifications (
  id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  account_id uuid NOT NULL REFERENCES public.accounts(id) ON DELETE CASCADE,
  module text NOT NULL CHECK (module IN ('courses', 'events', 'bookings')),
  trigger_event text NOT NULL,
  entity_id uuid NOT NULL,
  context jsonb NOT NULL DEFAULT '{}',
  processed_at timestamptz,
  created_at timestamptz NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS ix_pending_module_notifications_unprocessed
  ON public.pending_module_notifications(created_at)
  WHERE processed_at IS NULL;

ALTER TABLE public.pending_module_notifications ENABLE ROW LEVEL SECURITY;
REVOKE ALL ON public.pending_module_notifications FROM authenticated, service_role;
GRANT SELECT ON public.pending_module_notifications TO authenticated;
GRANT ALL ON public.pending_module_notifications TO service_role;

CREATE POLICY pending_module_notifications_select ON public.pending_module_notifications
  FOR SELECT TO authenticated USING (public.has_role_on_account(account_id));

-- Enqueue helper
CREATE OR REPLACE FUNCTION public.enqueue_module_notification(
  p_account_id uuid,
  p_module text,
  p_trigger_event text,
  p_entity_id uuid,
  p_context jsonb DEFAULT '{}'
)
RETURNS void
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = ''
AS $$
BEGIN
  INSERT INTO public.pending_module_notifications
    (account_id, module, trigger_event, entity_id, context)
  VALUES
    (p_account_id, p_module, p_trigger_event, p_entity_id, p_context);
END;
$$;

GRANT EXECUTE ON FUNCTION public.enqueue_module_notification(uuid, text, text, uuid, jsonb) TO authenticated;
GRANT EXECUTE ON FUNCTION public.enqueue_module_notification(uuid, text, text, uuid, jsonb) TO service_role;
