import { serve } from "https://deno.land/std@0.190.0/http/server.ts";
import { Novu } from "npm:@novu/api@1.6.0";

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

// Simple request tracking
const startRequest = () => ({ requestId: crypto.randomUUID(), start: Date.now() });
const endRequest = (tracking: { start: number }) => Date.now() - tracking.start;

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

  try {
    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 
    });

    // Parse and validate request body
    let requestBody;
    try {
      requestBody = await req.json();
    } catch (parseError) {
      return new Response(
        JSON.stringify({
          success: false,
          error: 'Invalid JSON in request body',
        }),
        {
          headers: { ...corsHeaders, 'Content-Type': 'application/json' },
          status: 400,
        }
      );
    }

    const { subscriberId, email, firstName, lastName, phone, avatar, data } = requestBody;

    // Validate required fields
    if (!subscriberId || typeof subscriberId !== 'string' || subscriberId.trim() === '') {
      return new Response(
        JSON.stringify({
          success: false,
          error: 'subscriberId is required and must be a non-empty string',
        }),
        {
          headers: { ...corsHeaders, 'Content-Type': 'application/json' },
          status: 400,
        }
      );
    }

    if (!email || typeof email !== 'string' || email.trim() === '') {
      return new Response(
        JSON.stringify({
          success: false,
          error: 'email is required and must be a non-empty string',
        }),
        {
          headers: { ...corsHeaders, 'Content-Type': 'application/json' },
          status: 400,
        }
      );
    }

    // Validate email format using regex
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(email)) {
      return new Response(
        JSON.stringify({
          success: false,
          error: 'Invalid email format. Please provide a valid email address',
        }),
        {
          headers: { ...corsHeaders, 'Content-Type': 'application/json' },
          status: 400,
        }
      );
    }

    // Validate optional fields if provided
    if (firstName !== undefined && firstName !== null && (typeof firstName !== 'string' || firstName.length > 100)) {
      return new Response(
        JSON.stringify({
          success: false,
          error: 'firstName must be a string with maximum 100 characters',
        }),
        {
          headers: { ...corsHeaders, 'Content-Type': 'application/json' },
          status: 400,
        }
      );
    }

    if (lastName !== undefined && lastName !== null && (typeof lastName !== 'string' || lastName.length > 100)) {
      return new Response(
        JSON.stringify({
          success: false,
          error: 'lastName must be a string with maximum 100 characters',
        }),
        {
          headers: { ...corsHeaders, 'Content-Type': 'application/json' },
          status: 400,
        }
      );
    }

    if (phone !== undefined && phone !== null) {
      if (typeof phone !== 'string') {
        return new Response(
          JSON.stringify({
            success: false,
            error: 'phone must be a string',
          }),
          {
            headers: { ...corsHeaders, 'Content-Type': 'application/json' },
            status: 400,
          }
        );
      }
      // Validate phone format (basic validation for international numbers)
      const phoneRegex = /^\+?[1-9]\d{1,14}$/;
      if (!phoneRegex.test(phone.replace(/[\s\-\(\)]/g, ''))) {
        return new Response(
          JSON.stringify({
            success: false,
            error: 'Invalid phone format. Please provide a valid international phone number',
          }),
          {
            headers: { ...corsHeaders, 'Content-Type': 'application/json' },
            status: 400,
          }
        );
      }
    }

    if (avatar !== undefined && avatar !== null && (typeof avatar !== 'string' || !avatar.startsWith('http'))) {
      return new Response(
        JSON.stringify({
          success: false,
          error: 'avatar must be a valid URL',
        }),
        {
          headers: { ...corsHeaders, 'Content-Type': 'application/json' },
          status: 400,
        }
      );
    }

    // Validate data field if provided
    if (data !== undefined && data !== null) {
      if (typeof data !== 'object' || Array.isArray(data)) {
        return new Response(
          JSON.stringify({
            success: false,
            error: 'data must be a valid object',
          }),
          {
            headers: { ...corsHeaders, 'Content-Type': 'application/json' },
            status: 400,
          }
        );
      }

      // Check data size (limit to 10KB serialized)
      const dataSize = JSON.stringify(data).length;
      if (dataSize > 10240) {
        return new Response(
          JSON.stringify({
            success: false,
            error: 'data field is too large (maximum 10KB)',
          }),
          {
            headers: { ...corsHeaders, 'Content-Type': 'application/json' },
            status: 400,
          }
        );
      }
    }

    console.log('Creating Novu subscriber:', { subscriberId, email, firstName });

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

    const duration = endRequest(tracking);
    console.log('Subscriber created successfully:', subscriber.data, { requestId: tracking.requestId, duration });

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

    return new Response(
      JSON.stringify({
        success: true,
        subscriberId: subscriber.data._id,
        requestId: tracking.requestId
      }),
      {
        headers: { ...corsHeaders, 'Content-Type': 'application/json', 'X-Request-ID': tracking.requestId },
        status: 200,
      }
    );
  } catch (error: any) {
    const duration = endRequest(tracking);
    console.error('Error creating Novu subscriber:', error, { requestId: tracking.requestId, duration });
    
    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,
      }
    );
  }
});
