-- =====================================================
-- Data Integrity Constraints for Courses, Events, Bookings
--
-- Adds CHECK constraints and partial unique indexes to
-- enforce business rules at the database level.
--
-- All constraint additions are idempotent — wrapped in
-- DO blocks that check pg_constraint before adding.
-- =====================================================

-- -------------------------------------------------------
-- COURSES
-- -------------------------------------------------------

-- reduced_fee must not exceed fee
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_reduced_fee_lte_fee'
  ) THEN
    ALTER TABLE public.courses
      ADD CONSTRAINT chk_courses_reduced_fee_lte_fee
      CHECK (reduced_fee IS NULL OR reduced_fee <= fee);
  END IF;
END;
$$;

-- min_participants must not exceed capacity
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_min_lte_capacity'
  ) THEN
    ALTER TABLE public.courses
      ADD CONSTRAINT chk_courses_min_lte_capacity
      CHECK (min_participants IS NULL OR min_participants <= capacity);
  END IF;
END;
$$;

-- end_date must be on or after start_date
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_date_range'
  ) THEN
    ALTER TABLE public.courses
      ADD CONSTRAINT chk_courses_date_range
      CHECK (end_date IS NULL OR start_date IS NULL OR end_date >= start_date);
  END IF;
END;
$$;

-- registration_deadline must be on or before start_date
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_courses_deadline_before_start'
  ) THEN
    ALTER TABLE public.courses
      ADD CONSTRAINT chk_courses_deadline_before_start
      CHECK (registration_deadline IS NULL OR start_date IS NULL OR registration_deadline <= start_date);
  END IF;
END;
$$;

-- Unique course_number per account (partial index — allows NULLs and empty strings)
CREATE UNIQUE INDEX IF NOT EXISTS uix_courses_number_per_account
  ON public.courses(account_id, course_number)
  WHERE course_number IS NOT NULL AND course_number != '';

-- -------------------------------------------------------
-- EVENTS
-- -------------------------------------------------------

-- min_age must not exceed max_age
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_events_age_range'
  ) THEN
    ALTER TABLE public.events
      ADD CONSTRAINT chk_events_age_range
      CHECK (min_age IS NULL OR max_age IS NULL OR min_age <= max_age);
  END IF;
END;
$$;

-- end_date must be on or after event_date
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_events_date_range'
  ) THEN
    ALTER TABLE public.events
      ADD CONSTRAINT chk_events_date_range
      CHECK (end_date IS NULL OR end_date >= event_date);
  END IF;
END;
$$;

-- registration_deadline must be on or before event_date
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_events_deadline_before_event'
  ) THEN
    ALTER TABLE public.events
      ADD CONSTRAINT chk_events_deadline_before_event
      CHECK (registration_deadline IS NULL OR registration_deadline <= event_date);
  END IF;
END;
$$;

-- -------------------------------------------------------
-- BOOKINGS
-- -------------------------------------------------------

-- At least 1 adult required
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_bookings_min_adults'
  ) THEN
    ALTER TABLE public.bookings
      ADD CONSTRAINT chk_bookings_min_adults
      CHECK (adults >= 1);
  END IF;
END;
$$;

-- total_price must be non-negative
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM pg_constraint WHERE conname = 'chk_bookings_price_non_negative'
  ) THEN
    ALTER TABLE public.bookings
      ADD CONSTRAINT chk_bookings_price_non_negative
      CHECK (total_price >= 0);
  END IF;
END;
$$;
