import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';

// POST /api/forum/votes — cast or toggle a vote
export async function POST(req: NextRequest) {
  try {
    const supabase = await createClient();
    const { data: { user } } = await supabase.auth.getUser();

    if (!user) {
      return NextResponse.json({ error: 'Authentication required to vote.' }, { status: 401 });
    }

    const body = await req.json();
    const { target_type, target_id, vote_value } = body;

    if (!target_type || !target_id || ![1, -1].includes(vote_value)) {
      return NextResponse.json({ error: 'Invalid vote parameters.' }, { status: 400 });
    }

    if (!['thread', 'reply'].includes(target_type)) {
      return NextResponse.json({ error: 'Invalid target_type.' }, { status: 400 });
    }

    // Ensure user_profiles row exists for this user
    const { data: profile } = await supabase
      .from('user_profiles')
      .select('id')
      .eq('id', user.id)
      .maybeSingle();

    if (!profile) {
      // Create profile stub if missing
      await supabase.from('user_profiles').upsert({
        id: user.id,
        email: user.email || '',
        full_name: user.user_metadata?.full_name || 'Community Member',
        reputation: 0,
      });
    }

    // Check for existing vote
    const { data: existing } = await supabase
      .from('forum_votes')
      .select('id, vote_value')
      .eq('user_id', user.id)
      .eq('target_type', target_type)
      .eq('target_id', target_id)
      .maybeSingle();

    let action: 'created' | 'updated' | 'removed' = 'created';
    let finalVote: number | null = vote_value;

    if (existing) {
      if (existing.vote_value === vote_value) {
        // Same vote — remove it (toggle off)
        const { error } = await supabase
          .from('forum_votes')
          .delete()
          .eq('id', existing.id);
        if (error) throw error;
        action = 'removed';
        finalVote = null;
      } else {
        // Different vote — update it
        const { error } = await supabase
          .from('forum_votes')
          .update({ vote_value, updated_at: new Date().toISOString() })
          .eq('id', existing.id);
        if (error) throw error;
        action = 'updated';
      }
    } else {
      // New vote
      const { error } = await supabase
        .from('forum_votes')
        .insert({
          user_id: user.id,
          target_type,
          target_id,
          vote_value,
        });
      if (error) throw error;
      action = 'created';
    }

    // Fetch updated vote counts
    const table = target_type === 'thread' ? 'forum_threads' : 'forum_replies';
    const { data: updated } = await supabase
      .from(table)
      .select('upvotes, downvotes, vote_score')
      .eq('id', target_id)
      .single();

    return NextResponse.json({
      action,
      vote: finalVote,
      upvotes: updated?.upvotes ?? 0,
      downvotes: updated?.downvotes ?? 0,
      vote_score: updated?.vote_score ?? 0,
    });
  } catch (err: any) {
    return NextResponse.json({ error: err.message }, { status: 500 });
  }
}

// GET /api/forum/votes?target_type=thread&target_id=xxx — get user's vote on a target
export async function GET(req: NextRequest) {
  try {
    const supabase = await createClient();
    const { data: { user } } = await supabase.auth.getUser();
    const { searchParams } = new URL(req.url);
    const target_type = searchParams.get('target_type');
    const target_id = searchParams.get('target_id');

    if (!target_type || !target_id) {
      return NextResponse.json({ vote: null });
    }

    if (!user) {
      return NextResponse.json({ vote: null });
    }

    const { data } = await supabase
      .from('forum_votes')
      .select('vote_value')
      .eq('user_id', user.id)
      .eq('target_type', target_type)
      .eq('target_id', target_id)
      .maybeSingle();

    return NextResponse.json({ vote: data?.vote_value ?? null });
  } catch (err: any) {
    return NextResponse.json({ error: err.message }, { status: 500 });
  }
}
