import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
import { Novu } from "npm:@novu/api@1.6.0";
import { startRequest, endRequest } from "../_shared/logger.ts";

const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-request-id',
};

serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders });
  }

  const tracking = startRequest('migrate-novu-users');

  try {
    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
    const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
    const novuApiKey = Deno.env.get('NOVU_API_KEY');

    if (!novuApiKey) {
      throw new Error('NOVU_API_KEY is not configured');
    }

    // Create Supabase client with service role for admin access
    const supabase = createClient(supabaseUrl, supabaseServiceKey);

    const novu = new Novu({ 
      secretKey: novuApiKey 
    });

    // Fetch users who don't have Novu subscriber IDs
    const { data: existingPrefs, error: prefsError } = await supabase
      .from('user_notification_preferences')
      .select('user_id')
      .not('novu_subscriber_id', 'is', null);

    if (prefsError) throw prefsError;

    const existingUserIds = existingPrefs?.map(p => p.user_id) || [];

    // Fetch all profiles with usernames
    let query = supabase
      .from('profiles')
      .select('user_id, username');

    // Only add the not filter if there are existing user IDs
    if (existingUserIds.length > 0) {
      query = query.not('user_id', 'in', `(${existingUserIds.join(',')})`);
    }

    const { data: profiles, error: profilesError } = await query;

    if (profilesError) throw profilesError;

    if (!profiles || profiles.length === 0) {
      endRequest(tracking, 200);
      
      return new Response(
        JSON.stringify({
          success: true,
          message: 'No users to migrate',
          results: [],
          requestId: tracking.requestId
        }),
        {
          headers: { 
            ...corsHeaders, 
            'Content-Type': 'application/json',
            'X-Request-ID': tracking.requestId
          },
          status: 200,
        }
      );
    }

    // Fetch user emails from auth.users using service role
    const userIds = profiles.map(p => p.user_id);
    const { data: authUsers, error: authError } = await supabase.auth.admin.listUsers();

    if (authError) throw authError;

    const userEmails = new Map(
      authUsers.users
        .filter(u => userIds.includes(u.id))
        .map(u => [u.id, u.email])
    );

    // Migrate users
    const results = [];
    for (const profile of profiles) {
      const email = userEmails.get(profile.user_id);

      if (!email) {
        results.push({
          userId: profile.user_id,
          email: 'No email found',
          success: false,
          error: 'User email not found',
        });
        continue;
      }

      try {
        const subscriber = await novu.subscribers.identify(profile.user_id, {
          email,
          firstName: profile.username,
          data: { userId: profile.user_id },
        });

        // Update the user's notification preferences with the Novu subscriber ID
        await supabase
          .from('user_notification_preferences')
          .upsert({
            user_id: profile.user_id,
            novu_subscriber_id: subscriber.data._id,
          });

        results.push({
          userId: profile.user_id,
          email,
          username: profile.username,
          success: true,
        });
      } catch (error: any) {
        results.push({
          userId: profile.user_id,
          email,
          success: false,
          error: error.message,
        });
      }

      // Small delay to avoid overwhelming the API
      await new Promise(resolve => setTimeout(resolve, 100));
    }

    endRequest(tracking, 200);

    return new Response(
      JSON.stringify({
        success: true,
        total: profiles.length,
        results,
        requestId: tracking.requestId
      }),
      {
        headers: { 
          ...corsHeaders, 
          'Content-Type': 'application/json',
          'X-Request-ID': tracking.requestId
        },
        status: 200,
      }
    );
  } catch (error: any) {
    console.error('Error migrating Novu users:', error);

    endRequest(tracking, 500, error.message);

    return new Response(
      JSON.stringify({
        success: false,
        error: error.message,
        requestId: tracking.requestId
      }),
      {
        headers: { 
          ...corsHeaders, 
          'Content-Type': 'application/json',
          'X-Request-ID': tracking.requestId
        },
        status: 500,
      }
    );
  }
});
