-- Notifications Migration for BroadcastBeat
-- Tracks thread replies, mentions, upvotes, and follow activity

-- ============================================================
-- 1. NOTIFICATIONS TABLE
-- ============================================================
CREATE TABLE IF NOT EXISTS public.notifications (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES public.user_profiles(id) ON DELETE CASCADE,
    type TEXT NOT NULL CHECK (type IN ('thread_reply', 'mention', 'upvote', 'follow')),
    title TEXT NOT NULL,
    body TEXT,
    link TEXT,
    actor_id UUID REFERENCES public.user_profiles(id) ON DELETE SET NULL,
    actor_name TEXT,
    is_read BOOLEAN DEFAULT false,
    created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX IF NOT EXISTS idx_notifications_user_id ON public.notifications(user_id);
CREATE INDEX IF NOT EXISTS idx_notifications_user_unread ON public.notifications(user_id, is_read) WHERE is_read = false;
CREATE INDEX IF NOT EXISTS idx_notifications_created_at ON public.notifications(created_at DESC);

-- ============================================================
-- 2. RLS POLICIES
-- ============================================================
ALTER TABLE public.notifications ENABLE ROW LEVEL SECURITY;

DROP POLICY IF EXISTS "Users can view own notifications" ON public.notifications;
CREATE POLICY "Users can view own notifications"
ON public.notifications FOR SELECT
USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Users can update own notifications" ON public.notifications;
CREATE POLICY "Users can update own notifications"
ON public.notifications FOR UPDATE
USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Users can delete own notifications" ON public.notifications;
CREATE POLICY "Users can delete own notifications"
ON public.notifications FOR DELETE
USING (auth.uid() = user_id);

DROP POLICY IF EXISTS "Service role can insert notifications" ON public.notifications;
CREATE POLICY "Service role can insert notifications"
ON public.notifications FOR INSERT
WITH CHECK (true);

-- ============================================================
-- 3. AUTO-NOTIFY ON FORUM REPLY
-- ============================================================
CREATE OR REPLACE FUNCTION public.notify_thread_reply()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
    v_thread_author UUID;
    v_thread_title TEXT;
    v_thread_id UUID;
BEGIN
    SELECT author_id, title, id INTO v_thread_author, v_thread_title, v_thread_id
    FROM public.forum_threads
    WHERE id = NEW.thread_id;

    -- Notify thread author (if not replying to own thread and not AI)
    IF v_thread_author IS NOT NULL
       AND v_thread_author <> NEW.author_id
       AND NEW.is_ai_response = false THEN
        INSERT INTO public.notifications (user_id, type, title, body, link, actor_id, actor_name)
        VALUES (
            v_thread_author,
            'thread_reply',
            'New reply to your thread',
            v_thread_title,
            '/forum/thread/' || v_thread_id::TEXT,
            NEW.author_id,
            NEW.author_name
        );
    END IF;
    RETURN NEW;
END;
$$;

DROP TRIGGER IF EXISTS trg_notify_thread_reply ON public.forum_replies;
CREATE TRIGGER trg_notify_thread_reply
AFTER INSERT ON public.forum_replies
FOR EACH ROW EXECUTE FUNCTION public.notify_thread_reply();

-- ============================================================
-- 4. AUTO-NOTIFY ON UPVOTE
-- ============================================================
CREATE OR REPLACE FUNCTION public.notify_upvote()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
    v_target_author UUID;
    v_target_title TEXT;
    v_link TEXT;
    v_voter_name TEXT;
BEGIN
    -- Only notify on upvotes (vote_value = 1)
    IF NEW.vote_value <> 1 THEN
        RETURN NEW;
    END IF;

    SELECT username INTO v_voter_name FROM public.user_profiles WHERE id = NEW.user_id;

    IF NEW.target_type = 'thread' THEN
        SELECT author_id, title INTO v_target_author, v_target_title
        FROM public.forum_threads WHERE id = NEW.target_id;
        v_link := '/forum/thread/' || NEW.target_id::TEXT;
    ELSE
        SELECT fr.author_id, ft.title INTO v_target_author, v_target_title
        FROM public.forum_replies fr
        JOIN public.forum_threads ft ON ft.id = fr.thread_id
        WHERE fr.id = NEW.target_id;
        v_link := '/forum/thread/' || (
            SELECT thread_id FROM public.forum_replies WHERE id = NEW.target_id
        )::TEXT;
    END IF;

    IF v_target_author IS NOT NULL AND v_target_author <> NEW.user_id THEN
        INSERT INTO public.notifications (user_id, type, title, body, link, actor_id, actor_name)
        VALUES (
            v_target_author,
            'upvote',
            'Someone upvoted your ' || NEW.target_type,
            v_target_title,
            v_link,
            NEW.user_id,
            COALESCE(v_voter_name, 'A member')
        );
    END IF;
    RETURN NEW;
END;
$$;

DROP TRIGGER IF EXISTS trg_notify_upvote ON public.forum_votes;
CREATE TRIGGER trg_notify_upvote
AFTER INSERT ON public.forum_votes
FOR EACH ROW EXECUTE FUNCTION public.notify_upvote();
