-- ExposedGays v6: Sniffies-style user hosting events (map parties)
-- Run on SUPABASE_01 after migration_v5_privacy.sql

CREATE TABLE IF NOT EXISTS public.hosting_events (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  host_id UUID NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
  title TEXT NOT NULL CHECK (char_length(title) <= 80),
  description TEXT NOT NULL DEFAULT '' CHECK (char_length(description) <= 2000),
  event_type TEXT NOT NULL DEFAULT 'custom'
    CHECK (event_type IN ('cum-dump', 'orgy', 'group', 'pnp', 'vanilla', 'gloryhole', 'custom')),
  status TEXT NOT NULL DEFAULT 'scheduled'
    CHECK (status IN ('scheduled', 'live', 'ended', 'cancelled')),
  starts_at TIMESTAMPTZ NOT NULL,
  ends_at TIMESTAMPTZ NOT NULL,
  location GEOGRAPHY(POINT, 4326) NOT NULL,
  city TEXT,
  auto_accept BOOLEAN NOT NULL DEFAULT false,
  max_guests INTEGER CHECK (max_guests IS NULL OR max_guests BETWEEN 1 AND 500),
  tags TEXT[] NOT NULL DEFAULT '{}',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  CHECK (ends_at > starts_at)
);

CREATE INDEX IF NOT EXISTS idx_hosting_events_host ON public.hosting_events (host_id);
CREATE INDEX IF NOT EXISTS idx_hosting_events_status ON public.hosting_events (status);
CREATE INDEX IF NOT EXISTS idx_hosting_events_starts ON public.hosting_events (starts_at);
CREATE INDEX IF NOT EXISTS idx_hosting_events_location ON public.hosting_events USING GIST (location);

CREATE TABLE IF NOT EXISTS public.hosting_event_media (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  event_id UUID NOT NULL REFERENCES public.hosting_events(id) ON DELETE CASCADE,
  media_type TEXT NOT NULL CHECK (media_type IN ('photo', 'video')),
  url TEXT NOT NULL,
  thumbnail_url TEXT,
  sort_order INTEGER NOT NULL DEFAULT 0,
  created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

CREATE INDEX IF NOT EXISTS idx_hosting_event_media_event ON public.hosting_event_media (event_id);

CREATE TABLE IF NOT EXISTS public.hosting_event_attendees (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  event_id UUID NOT NULL REFERENCES public.hosting_events(id) ON DELETE CASCADE,
  user_id UUID NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
  status TEXT NOT NULL DEFAULT 'requested'
    CHECK (status IN ('invited', 'requested', 'accepted', 'declined', 'cancelled')),
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  UNIQUE (event_id, user_id)
);

CREATE INDEX IF NOT EXISTS idx_hosting_event_attendees_event ON public.hosting_event_attendees (event_id);
CREATE INDEX IF NOT EXISTS idx_hosting_event_attendees_user ON public.hosting_event_attendees (user_id);

-- Max 2 photos + 1 video per event
CREATE OR REPLACE FUNCTION public.enforce_hosting_event_media_limit()
RETURNS TRIGGER AS $$
DECLARE
  photo_count INTEGER;
  video_count INTEGER;
BEGIN
  SELECT COUNT(*) INTO photo_count
  FROM public.hosting_event_media
  WHERE event_id = NEW.event_id AND media_type = 'photo';

  SELECT COUNT(*) INTO video_count
  FROM public.hosting_event_media
  WHERE event_id = NEW.event_id AND media_type = 'video';

  IF NEW.media_type = 'photo' AND photo_count >= 2 THEN
    RAISE EXCEPTION 'Maximum 2 photos per hosting event';
  END IF;

  IF NEW.media_type = 'video' AND video_count >= 1 THEN
    RAISE EXCEPTION 'Maximum 1 video per hosting event';
  END IF;

  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_hosting_event_media_limit ON public.hosting_event_media;
CREATE TRIGGER trg_hosting_event_media_limit
  BEFORE INSERT ON public.hosting_event_media
  FOR EACH ROW EXECUTE FUNCTION public.enforce_hosting_event_media_limit();

CREATE OR REPLACE FUNCTION public.touch_hosting_event_updated()
RETURNS TRIGGER AS $$
BEGIN
  UPDATE public.hosting_events SET updated_at = now() WHERE id = NEW.event_id;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS trg_hosting_event_attendee_touch ON public.hosting_event_attendees;
CREATE TRIGGER trg_hosting_event_attendee_touch
  AFTER INSERT OR UPDATE ON public.hosting_event_attendees
  FOR EACH ROW EXECUTE FUNCTION public.touch_hosting_event_updated();

ALTER TABLE public.hosting_events ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.hosting_event_media ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.hosting_event_attendees ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Hosting events viewable by authenticated users"
  ON public.hosting_events FOR SELECT
  USING (auth.role() = 'authenticated' AND status != 'cancelled');

CREATE POLICY "Users can create hosting events"
  ON public.hosting_events FOR INSERT
  WITH CHECK (auth.uid() = host_id);

CREATE POLICY "Hosts can update own events"
  ON public.hosting_events FOR UPDATE
  USING (auth.uid() = host_id);

CREATE POLICY "Hosts can delete own events"
  ON public.hosting_events FOR DELETE
  USING (auth.uid() = host_id);

CREATE POLICY "Event media viewable by authenticated users"
  ON public.hosting_event_media FOR SELECT
  USING (auth.role() = 'authenticated');

CREATE POLICY "Hosts manage event media"
  ON public.hosting_event_media FOR ALL
  USING (
    EXISTS (
      SELECT 1 FROM public.hosting_events e
      WHERE e.id = event_id AND e.host_id = auth.uid()
    )
  );

CREATE POLICY "Attendees viewable by authenticated users"
  ON public.hosting_event_attendees FOR SELECT
  USING (auth.role() = 'authenticated');

CREATE POLICY "Users manage own attendance"
  ON public.hosting_event_attendees FOR INSERT
  WITH CHECK (auth.uid() = user_id);

CREATE POLICY "Users update own attendance"
  ON public.hosting_event_attendees FOR UPDATE
  USING (auth.uid() = user_id OR EXISTS (
    SELECT 1 FROM public.hosting_events e
    WHERE e.id = event_id AND e.host_id = auth.uid()
  ));

CREATE POLICY "Hosts delete attendees"
  ON public.hosting_event_attendees FOR DELETE
  USING (
    auth.uid() = user_id OR EXISTS (
      SELECT 1 FROM public.hosting_events e
      WHERE e.id = event_id AND e.host_id = auth.uid()
    )
  );

ALTER PUBLICATION supabase_realtime ADD TABLE public.hosting_events;
ALTER PUBLICATION supabase_realtime ADD TABLE public.hosting_event_attendees;

INSERT INTO storage.buckets (id, name, public)
VALUES ('hosting-events', 'hosting-events', true)
ON CONFLICT (id) DO NOTHING;