import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
import { Novu } from "npm:@novu/api@1.6.0";
import { corsHeadersWithTracing as corsHeaders } from '../_shared/cors.ts';
import { edgeLogger } from "../_shared/logger.ts";
import { createEdgeFunction } from '../_shared/edgeFunctionWrapper.ts';

export default createEdgeFunction(
  {
    name: 'migrate-novu-users',
    requireAuth: false,
    corsHeaders: corsHeaders
  },
  async (req, context) => {
    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');
    }

    context.span.setAttribute('action', 'migrate_novu_users');

    // 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) {
      return new Response(
        JSON.stringify({
          success: true,
          message: 'No users to migrate',
          results: [],
        }),
        {
          headers: { 
            'Content-Type': 'application/json',
          },
          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));
    }

    edgeLogger.info('Migration complete', { 
      requestId: context.requestId,
      total: profiles.length,
      successful: results.filter(r => r.success).length
    });

    return new Response(
      JSON.stringify({
        success: true,
        total: profiles.length,
        results,
      }),
      {
        headers: { 
          'Content-Type': 'application/json',
        },
        status: 200,
      }
    );
  }
);
