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

export default createEdgeFunction(
  {
    name: 'update-novu-preferences',
    requireAuth: false,
    corsHeaders: corsHeaders
  },
  async (req, context) => {
    const novuApiKey = Deno.env.get('NOVU_API_KEY');
    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
    const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;

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

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

    const supabase = createClient(supabaseUrl, supabaseServiceKey);

    const { userId, preferences } = await req.json();

    context.span.setAttribute('action', 'update_novu_preferences');
    edgeLogger.info('Updating preferences for user', { userId, requestId: context.requestId });

    // Validate input
    if (!userId) {
      throw new Error('userId is required');
    }

    if (!preferences?.channelPreferences) {
      throw new Error('channelPreferences is required in preferences object');
    }

    // Get Novu subscriber ID from database
    const { data: prefData, error: prefError } = await supabase
      .from('user_notification_preferences')
      .select('novu_subscriber_id')
      .eq('user_id', userId)
      .single();

    if (prefError || !prefData?.novu_subscriber_id) {
      throw new Error('Novu subscriber not found');
    }

    const subscriberId = prefData.novu_subscriber_id;

    // Update channel preferences in Novu
    // Note: Novu's updatePreference updates one channel at a time for a specific workflow
    const channelPrefs = preferences.channelPreferences;
    const workflowId = preferences.workflowId || 'default';
    
    const channelTypes = ['email', 'sms', 'in_app', 'push'] as const;
    const results: { channel: string; success: boolean; error?: string }[] = [];
    
    for (const channelType of channelTypes) {
      if (channelPrefs[channelType] !== undefined) {
        try {
          await novu.subscribers.updatePreference(
            subscriberId,
            workflowId,
            {
              channel: {
                type: channelType as any, // Cast to any to handle SDK type limitations
                enabled: channelPrefs[channelType]
              },
            }
          );
          results.push({ channel: channelType, success: true });
        } catch (channelError: any) {
          edgeLogger.error('Failed to update channel preference', { 
            channel: channelType, 
            error: channelError.message,
            requestId: context.requestId
          });
          results.push({ 
            channel: channelType, 
            success: false, 
            error: channelError.message || 'Unknown error' 
          });
        }
      }
    }

    // Check if any updates failed
    const failedChannels = results.filter(r => !r.success);
    const allSucceeded = failedChannels.length === 0;

    if (!allSucceeded) {
      edgeLogger.warn('Some channel preferences failed to update', { 
        failedChannels: failedChannels.map(c => c.channel),
        requestId: context.requestId
      });
      throw new Error('Some channel preferences failed to update: ' + failedChannels.map(c => c.channel).join(', '));
    }

    edgeLogger.info('All preferences updated successfully', { 
      requestId: context.requestId
    });
    
    return new Response(
      JSON.stringify({
        success: true,
        results,
      }),
      {
        headers: { 'Content-Type': 'application/json' },
        status: 200,
      }
    );
  }
);
