import { getSupabaseAdmin } from '@/lib/supabase/server';
import { MILESTONE_LABELS, type MilestoneType } from '@/lib/types/success-tracking';

/**
 * Record a milestone for a user.
 * Uses service role to bypass RLS (system-initiated tracking).
 * Silently ignores duplicate unique milestones (ON CONFLICT DO NOTHING).
 */
export async function recordMilestone(
  userId: string,
  userType: 'worker' | 'contractor',
  milestoneType: MilestoneType,
  metadata?: Record<string, unknown>
): Promise<boolean> {
  try {
    const admin = getSupabaseAdmin();

    const { error } = await admin
      .from('success_milestones')
      .upsert(
        {
          user_id: userId,
          user_type: userType,
          milestone_type: milestoneType,
          metadata: metadata || {},
        },
        {
          // For unique-once milestones, ignore duplicates
          onConflict: 'user_id,milestone_type',
          ignoreDuplicates: true,
        }
      );

    if (error) {
      // If it's a unique violation on the partial index, that's fine — milestone already recorded
      if (error.code === '23505') return false;
      console.error(`Failed to record milestone ${milestoneType} for ${userId}:`, error);
      return false;
    }

    // Update success_candidates score
    await updateCandidateScore(userId, userType);

    return true;
  } catch (err) {
    console.error('recordMilestone error:', err);
    return false;
  }
}

/**
 * Record a repeatable milestone (repeat_hire, five_star_given, five_star_received).
 * These don't have unique constraints so we always insert.
 */
export async function recordRepeatMilestone(
  userId: string,
  userType: 'worker' | 'contractor',
  milestoneType: 'repeat_hire' | 'five_star_given' | 'five_star_received' | 'referral_converted',
  metadata?: Record<string, unknown>
): Promise<boolean> {
  try {
    const admin = getSupabaseAdmin();

    const { error } = await admin
      .from('success_milestones')
      .insert({
        user_id: userId,
        user_type: userType,
        milestone_type: milestoneType,
        metadata: metadata || {},
      });

    if (error) {
      console.error(`Failed to record repeat milestone ${milestoneType} for ${userId}:`, error);
      return false;
    }

    await updateCandidateScore(userId, userType);
    return true;
  } catch (err) {
    console.error('recordRepeatMilestone error:', err);
    return false;
  }
}

/**
 * Recompute a user's success candidate score based on their milestones and NPS.
 * Upserts into success_candidates table.
 */
async function updateCandidateScore(
  userId: string,
  userType: 'worker' | 'contractor'
): Promise<void> {
  try {
    const admin = getSupabaseAdmin();

    // Get all milestones for this user
    const { data: milestones } = await admin
      .from('success_milestones')
      .select('milestone_type, created_at')
      .eq('user_id', userId)
      .order('created_at', { ascending: false });

    // Get latest NPS score
    const { data: surveys } = await admin
      .from('success_surveys')
      .select('nps_score')
      .eq('user_id', userId)
      .not('nps_score', 'is', null)
      .order('created_at', { ascending: false })
      .limit(1);

    // Get user profile info
    const { data: profile } = await admin
      .from('profiles')
      .select('name, email')
      .eq('id', userId)
      .single();

    const milestoneCount = milestones?.length || 0;
    const latestMilestone = milestones?.[0]?.milestone_type || null;
    const npsScore = surveys?.[0]?.nps_score ?? null;

    // Compute score: sum of milestone points + NPS bonus
    let score = 0;
    if (milestones) {
      for (const m of milestones) {
        const config = MILESTONE_LABELS[m.milestone_type as MilestoneType];
        if (config) score += config.points;
      }
    }
    // NPS bonus: promoters (9-10) get +10, passives (7-8) get +3, detractors (0-6) get -5
    if (npsScore !== null) {
      if (npsScore >= 9) score += 10;
      else if (npsScore >= 7) score += 3;
      else score -= 5;
    }

    // Upsert candidate record
    await admin
      .from('success_candidates')
      .upsert(
        {
          user_id: userId,
          user_type: userType,
          user_name: profile?.name || null,
          user_email: profile?.email || null,
          score,
          milestone_count: milestoneCount,
          latest_milestone: latestMilestone,
          nps_score: npsScore,
        },
        { onConflict: 'user_id' }
      );
  } catch (err) {
    console.error('updateCandidateScore error:', err);
  }
}
