-- Migration: add scheduled_notifications queue and enqueue function for shift reminders
-- Creates a queue table and stored procedure to enqueue 15-minute and end-of-shift reminders

CREATE EXTENSION IF NOT EXISTS pgcrypto;

-- Queue table for scheduled notifications
CREATE TABLE IF NOT EXISTS public.scheduled_notifications (
  id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  schedule_id uuid NOT NULL REFERENCES public.duty_schedules(id) ON DELETE CASCADE,
  user_id uuid NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  notify_type text NOT NULL, -- 'start_15' | 'end'
  scheduled_for timestamptz NOT NULL,
  created_at timestamptz NOT NULL DEFAULT now(),
  processed boolean NOT NULL DEFAULT false,
  processed_at timestamptz,
  retry_count int NOT NULL DEFAULT 0,
  last_error text
);

CREATE INDEX IF NOT EXISTS idx_scheduled_notifications_scheduled_for ON public.scheduled_notifications(scheduled_for);
CREATE INDEX IF NOT EXISTS idx_scheduled_notifications_processed ON public.scheduled_notifications(processed);

-- Ensure uniqueness per schedule/user/notify type
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint c
    JOIN pg_class t ON c.conrelid = t.oid
    WHERE c.conname = 'uniq_sched_user_type' AND t.relname = 'scheduled_notifications'
  ) THEN
    ALTER TABLE public.scheduled_notifications ADD CONSTRAINT uniq_sched_user_type UNIQUE (schedule_id, user_id, notify_type);
  END IF;
END$$;

-- The project already has notification_pushes and try_mark_notification_pushed (see earlier migrations).

-- Enqueue function: finds duty_schedules in the configured windows and inserts into queue.
CREATE OR REPLACE FUNCTION public.enqueue_due_shift_notifications()
RETURNS void LANGUAGE plpgsql AS $$
DECLARE
  rec RECORD;
BEGIN
  -- 15-minute-before reminders
  FOR rec IN
    SELECT id AS schedule_id, user_id AS user_id, start_time AS start_at
    FROM public.duty_schedules
    WHERE start_time BETWEEN now() + interval '15 minutes' - interval '30 seconds' AND now() + interval '15 minutes' + interval '30 seconds'
      AND status IN ('arrival', 'late')
  LOOP
    -- Skip if user already checked in for this duty (attendance_logs references duty_schedule_id)
    IF EXISTS (SELECT 1 FROM public.attendance_logs al WHERE al.duty_schedule_id = rec.schedule_id AND al.check_in_at IS NOT NULL) THEN
      CONTINUE;
    END IF;

    INSERT INTO public.scheduled_notifications (schedule_id, user_id, notify_type, scheduled_for)
    VALUES (rec.schedule_id, rec.user_id, 'start_15', rec.start_at)
    ON CONFLICT (schedule_id, user_id, notify_type) DO NOTHING;
  END LOOP;

  -- End-of-shift reminders (near exact end)
  FOR rec IN
    SELECT id AS schedule_id, user_id AS user_id, end_time AS end_at
    FROM public.duty_schedules
    WHERE end_time BETWEEN now() - interval '30 seconds' AND now() + interval '30 seconds'
      AND status IN ('arrival', 'late')
  LOOP
    INSERT INTO public.scheduled_notifications (schedule_id, user_id, notify_type, scheduled_for)
    VALUES (rec.schedule_id, rec.user_id, 'end', rec.end_at)
    ON CONFLICT (schedule_id, user_id, notify_type) DO NOTHING;
  END LOOP;
END;
$$;

-- NOTE: Schedule this function with pg_cron or your Postgres scheduler. Example (requires pg_cron extension enabled):
-- SELECT cron.schedule('shift_reminders_every_min', '*/1 * * * *', $$SELECT public.enqueue_due_shift_notifications();$$);
