import { serve } from "https://deno.land/std@0.190.0/http/server.ts";
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.57.4";
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',
};

interface RequestBody {
  submission_id: string;
  user_id: string;
  submission_type: string;
  status: 'approved' | 'rejected';
  reviewer_notes?: string;
}

async function constructEntityURL(
  supabase: any,
  submissionType: string,
  itemData: any
): Promise<string> {
  const baseURL = 'https://www.thrillwiki.com';
  
  if (submissionType === 'park') {
    const parkSlug = itemData.slug;
    return `${baseURL}/parks/${parkSlug}`;
  }
  
  if (submissionType === 'ride') {
    const rideSlug = itemData.slug;
    const parkId = itemData.park_id;
    
    if (!parkId) {
      return `${baseURL}/rides/${rideSlug}`;
    }
    
    // Fetch park slug
    const { data: park } = await supabase
      .from('parks')
      .select('slug')
      .eq('id', parkId)
      .maybeSingle();
    
    const parkSlug = park?.slug || 'unknown';
    return `${baseURL}/parks/${parkSlug}/rides/${rideSlug}`;
  }
  
  if (submissionType === 'company') {
    const companySlug = itemData.slug;
    const companyType = itemData.company_type;
    
    if (companyType === 'manufacturer') {
      return `${baseURL}/manufacturers/${companySlug}`;
    } else if (companyType === 'operator') {
      return `${baseURL}/operators/${companySlug}`;
    } else if (companyType === 'property_owner') {
      return `${baseURL}/owners/${companySlug}`;
    } else if (companyType === 'designer') {
      return `${baseURL}/designers/${companySlug}`;
    }
    return `${baseURL}/companies/${companySlug}`;
  }
  
  if (submissionType === 'ride_model') {
    const modelSlug = itemData.slug;
    const manufacturerId = itemData.manufacturer_id;
    
    if (!manufacturerId) {
      return `${baseURL}/models/${modelSlug}`;
    }
    
    // Fetch manufacturer slug
    const { data: manufacturer } = await supabase
      .from('companies')
      .select('slug')
      .eq('id', manufacturerId)
      .eq('company_type', 'manufacturer')
      .maybeSingle();
    
    const manufacturerSlug = manufacturer?.slug || 'unknown';
    return `${baseURL}/manufacturers/${manufacturerSlug}/models/${modelSlug}`;
  }
  
  return `${baseURL}`;
}

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

  const tracking = startRequest('notify-user-submission-status');

  try {
    const supabaseUrl = Deno.env.get('SUPABASE_URL')!;
    const supabaseServiceKey = Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!;
    
    const supabase = createClient(supabaseUrl, supabaseServiceKey);

    const { submission_id, user_id, submission_type, status, reviewer_notes } = await req.json() as RequestBody;

    // Fetch submission items to get entity data
    const { data: items, error: itemsError } = await supabase
      .from('submission_items')
      .select('item_data')
      .eq('submission_id', submission_id)
      .order('order_index', { ascending: true })
      .limit(1)
      .maybeSingle();

    if (itemsError) {
      throw new Error(`Failed to fetch submission items: ${itemsError.message}`);
    }

    if (!items || !items.item_data) {
      throw new Error('No submission items found');
    }

    // Extract entity data
    const entityName = items.item_data.name || 'your submission';
    const entityType = submission_type.replace('_', ' ');
    
    // Construct entity URL
    const entityURL = await constructEntityURL(supabase, submission_type, items.item_data);

    // Determine workflow and build payload based on status
    const workflowId = status === 'approved' ? 'submission-approved' : 'submission-rejected';
    
    let payload: Record<string, string>;
    
    if (status === 'approved') {
      // Approval payload
      payload = {
        baseUrl: 'https://www.thrillwiki.com',
        entityType,
        entityName,
        submissionId: submission_id,
        entityURL,
        moderationNotes: reviewer_notes || '',
      };
    } else {
      // Rejection payload
      payload = {
        baseUrl: 'https://www.thrillwiki.com',
        rejectionReason: reviewer_notes || 'No reason provided',
        entityType,
        entityName,
        entityURL,
        actualStatus: 'rejected',
      };
    }

    // Generate idempotency key for duplicate prevention
    const { data: keyData, error: keyError } = await supabase
      .rpc('generate_notification_idempotency_key', {
        p_notification_type: `submission_${status}`,
        p_entity_id: submission_id,
        p_recipient_id: user_id,
      });

    const idempotencyKey = keyData || `user_sub_${submission_id}_${user_id}_${status}_${Date.now()}`;

    // Check for duplicate within 24h window
    const { data: existingLog, error: logCheckError } = await supabase
      .from('notification_logs')
      .select('id')
      .eq('user_id', user_id)
      .eq('idempotency_key', idempotencyKey)
      .gte('created_at', new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString())
      .maybeSingle();

    if (existingLog) {
      // Duplicate detected - log and skip
      await supabase.from('notification_logs').update({
        is_duplicate: true
      }).eq('id', existingLog.id);

      console.log('Duplicate notification prevented:', { 
        userId: user_id,
        idempotencyKey,
        submissionId: submission_id,
        requestId: tracking.requestId 
      });

      endRequest(tracking, 200);

      return new Response(
        JSON.stringify({
          success: true,
          message: 'Duplicate notification prevented',
          idempotencyKey,
          requestId: tracking.requestId
        }),
        {
          headers: { 
            ...corsHeaders, 
            'Content-Type': 'application/json',
            'X-Request-ID': tracking.requestId
          },
          status: 200,
        }
      );
    }

    console.log('Sending notification to user:', { 
      userId: user_id, 
      workflowId, 
      entityName,
      status,
      idempotencyKey,
      requestId: tracking.requestId 
    });

    // Call trigger-notification function
    const { data: notificationResult, error: notificationError } = await supabase.functions.invoke(
      'trigger-notification',
      {
        body: {
          workflowId,
          subscriberId: user_id,
          payload,
        },
      }
    );

    if (notificationError) {
      throw new Error(`Failed to trigger notification: ${notificationError.message}`);
    }

    // Log notification in notification_logs with idempotency key
    await supabase.from('notification_logs').insert({
      user_id,
      notification_type: `submission_${status}`,
      idempotency_key: idempotencyKey,
      is_duplicate: false,
      metadata: {
        submission_id,
        submission_type,
        transaction_id: notificationResult?.transactionId
      }
    });

    console.log('User notification sent successfully:', notificationResult);

    endRequest(tracking, 200);

    return new Response(
      JSON.stringify({
        success: true,
        transactionId: notificationResult?.transactionId,
        requestId: tracking.requestId
      }),
      {
        headers: { 
          ...corsHeaders, 
          'Content-Type': 'application/json',
          'X-Request-ID': tracking.requestId
        },
        status: 200,
      }
    );
  } catch (error: unknown) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
    console.error('Error notifying user about submission status:', errorMessage);
    
    endRequest(tracking, 500, errorMessage);

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