import { Novu } from "npm:@novu/api@1.6.0";
import { corsHeaders } from '../_shared/cors.ts';
import { edgeLogger } from '../_shared/logger.ts';
import { formatEdgeError } from '../_shared/errorFormatter.ts';
import { createEdgeFunction } from '../_shared/edgeFunctionWrapper.ts';
import { validateString } from '../_shared/typeValidation.ts';

export default createEdgeFunction(
  {
    name: 'create-novu-subscriber',
    requireAuth: false,
    corsHeaders: corsHeaders
  },
  async (req, context) => {
    const novuApiKey = Deno.env.get('NOVU_API_KEY');
    
    if (!novuApiKey) {
      throw new Error('NOVU_API_KEY is not configured');
    }

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

    const { subscriberId, email, firstName, lastName, phone, avatar, data } = await req.json();

    // Validate required fields
    validateString(subscriberId, 'subscriberId', { requestId: context.requestId });
    validateString(email, 'email', { requestId: context.requestId });

    // Validate email format
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      throw new Error('Invalid email format. Please provide a valid email address');
    }

    // Validate optional fields if provided
    if (firstName !== undefined && firstName !== null && (typeof firstName !== 'string' || firstName.length > 100)) {
      throw new Error('firstName must be a string with maximum 100 characters');
    }

    if (lastName !== undefined && lastName !== null && (typeof lastName !== 'string' || lastName.length > 100)) {
      throw new Error('lastName must be a string with maximum 100 characters');
    }

    if (phone !== undefined && phone !== null) {
      if (typeof phone !== 'string') {
        throw new Error('phone must be a string');
      }
      const phoneRegex = /^\+?[1-9]\d{1,14}$/;
      if (!phoneRegex.test(phone.replace(/[\s\-\(\)]/g, ''))) {
        throw new Error('Invalid phone format. Please provide a valid international phone number');
      }
    }

    if (avatar !== undefined && avatar !== null && (typeof avatar !== 'string' || !avatar.startsWith('http'))) {
      throw new Error('avatar must be a valid URL');
    }

    if (data !== undefined && data !== null) {
      if (typeof data !== 'object' || Array.isArray(data)) {
        throw new Error('data must be a valid object');
      }
      const dataSize = JSON.stringify(data).length;
      if (dataSize > 10240) {
        throw new Error('data field is too large (maximum 10KB)');
      }
    }

    context.span.setAttribute('action', 'create_novu_subscriber');
    edgeLogger.info('Creating Novu subscriber', { subscriberId, email: '***', firstName, requestId: context.requestId });

    const subscriber = await novu.subscribers.identify(subscriberId, {
      email,
      firstName,
      lastName,
      phone,
      avatar,
      data,
    });

    edgeLogger.info('Subscriber created successfully', { 
      subscriberId: subscriber.data._id, 
      requestId: context.requestId
    });

    // Add subscriber to "users" topic for global announcements
    try {
      edgeLogger.info('Adding subscriber to users topic', { subscriberId, requestId: context.requestId });
      await novu.topics.addSubscribers('users', {
        subscribers: [subscriberId],
      });
      edgeLogger.info('Successfully added subscriber to users topic', { subscriberId, requestId: context.requestId });
    } catch (topicError: unknown) {
      // Non-blocking - log error but don't fail the request
      edgeLogger.error('Failed to add subscriber to users topic', { 
        error: formatEdgeError(topicError),
        subscriberId, 
        requestId: context.requestId 
      });
    }

    return new Response(
      JSON.stringify({
        success: true,
        subscriberId: subscriber.data._id,
      }),
      {
        headers: { 'Content-Type': 'application/json' },
        status: 200,
      }
    );
  }
);
