import { serve } from "https://deno.land/std@0.190.0/http/server.ts";
import { corsHeaders } from '../_shared/cors.ts';
import { createEdgeFunction, type EdgeFunctionContext } from '../_shared/edgeFunctionWrapper.ts';
import { addSpanEvent } from '../_shared/logger.ts';

interface AdminReplyRequest {
  submissionId: string;
  replyBody: string;
  replySubject?: string;
}

const handler = async (req: Request, { supabase, user, span, requestId }: EdgeFunctionContext): Promise<Response> => {
  const body: AdminReplyRequest = await req.json();
  const { submissionId, replyBody, replySubject } = body;

  // Validate request
  if (!submissionId || !replyBody) {
    addSpanEvent(span, 'validation_failed', { reason: 'missing_fields' });
    return new Response(
      JSON.stringify({ error: 'Missing required fields', requestId }),
      { status: 400, headers: { 'Content-Type': 'application/json' } }
    );
  }

  if (replyBody.length < 10 || replyBody.length > 5000) {
    addSpanEvent(span, 'validation_failed', { reason: 'invalid_length', length: replyBody.length });
    return new Response(
      JSON.stringify({ error: 'Reply must be between 10 and 5000 characters', requestId }),
      { status: 400, headers: { 'Content-Type': 'application/json' } }
    );
  }

  addSpanEvent(span, 'request_validated', { submissionId });

  // Get admin email from environment variable
  const adminEmail = Deno.env.get('ADMIN_EMAIL_ADDRESS') || 'admins@thrillwiki.com';
  const adminDisplayName = Deno.env.get('ADMIN_EMAIL_DISPLAY_NAME') || 'ThrillWiki Admin';

  // Fetch admin's profile for signature
  const { data: adminProfile } = await supabase
    .from('profiles')
    .select('display_name, username')
    .eq('user_id', user.id)
    .single();

  const adminName = adminProfile?.display_name || adminProfile?.username || 'ThrillWiki Team';

  // Fetch submission
  const { data: submission, error: fetchError } = await supabase
    .from('contact_submissions')
    .select('id, email, name, subject, thread_id, response_count, ticket_number')
    .eq('id', submissionId)
    .single();

  if (fetchError || !submission) {
    addSpanEvent(span, 'submission_not_found', { submissionId });
    return new Response(
      JSON.stringify({ error: 'Submission not found', requestId }),
      { status: 404, headers: { 'Content-Type': 'application/json' } }
    );
  }

  addSpanEvent(span, 'submission_fetched', { 
    ticketNumber: submission.ticket_number,
    recipientEmail: submission.email 
  });

  // Fetch email signature from admin settings
  const { data: signatureSetting } = await supabase
    .from('admin_settings')
    .select('setting_value')
    .eq('setting_key', 'email.signature')
    .single();

  const emailSignature = signatureSetting?.setting_value?.signature || '';
  
  // Build signature with admin name + global signature
  const finalReplyBody = emailSignature 
    ? `${replyBody}\n\n---\n${adminName}\n${emailSignature}`
    : `${replyBody}\n\n---\n${adminName}`;

  // Rate limiting: max 10 replies per hour
  const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();
  const { count } = await supabase
    .from('contact_email_threads')
    .select('*', { count: 'exact', head: true })
    .eq('submission_id', submissionId)
    .eq('direction', 'outbound')
    .gte('created_at', oneHourAgo);

  if (count && count >= 10) {
    addSpanEvent(span, 'rate_limit_exceeded', { count });
    return new Response(
      JSON.stringify({ error: 'Rate limit exceeded. Max 10 replies per hour.', requestId }),
      { status: 429, headers: { 'Content-Type': 'application/json' } }
    );
  }

  const ticketNumber = submission.ticket_number || 'UNKNOWN';
  const messageId = `<${ticketNumber}.${crypto.randomUUID()}@thrillwiki.com>`;
  const finalSubject = replySubject || `Re: [${ticketNumber}] ${submission.subject}`;
  
  // Get previous message for threading
  const { data: previousMessages } = await supabase
    .from('contact_email_threads')
    .select('message_id')
    .eq('submission_id', submissionId)
    .order('created_at', { ascending: false })
    .limit(1);

  const originalMessageId = `<${ticketNumber}.${submission.id}@thrillwiki.com>`;
  const inReplyTo = previousMessages?.[0]?.message_id || originalMessageId;
  
  // Build reference chain for threading
  const referenceChain = previousMessages?.[0]?.message_id 
    ? [originalMessageId, previousMessages[0].message_id].join(' ')
    : originalMessageId;

  addSpanEvent(span, 'sending_email', { 
    messageId,
    recipient: submission.email,
    subject: finalSubject 
  });

  // Send email via ForwardEmail
  const forwardEmailResponse = await fetch('https://api.forwardemail.net/v1/emails', {
    method: 'POST',
    headers: {
      'Authorization': `Basic ${btoa(Deno.env.get('FORWARDEMAIL_API_KEY') + ':')}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      from: `${adminDisplayName} <${adminEmail}>`,
      to: `${submission.name} <${submission.email}>`,
      subject: finalSubject,
      text: finalReplyBody,
      headers: {
        'Message-ID': messageId,
        'In-Reply-To': inReplyTo,
        'References': referenceChain,
        'X-Thread-ID': submission.thread_id,
        'X-Ticket-Number': ticketNumber
      }
    })
  });

  if (!forwardEmailResponse.ok) {
    const errorText = await forwardEmailResponse.text();
    addSpanEvent(span, 'email_send_failed', { 
      status: forwardEmailResponse.status,
      error: errorText 
    });
    throw new Error(`ForwardEmail API error: ${errorText}`);
  }

  addSpanEvent(span, 'email_sent', { messageId });

  // Insert email thread record
  const { error: insertError } = await supabase
    .from('contact_email_threads')
    .insert({
      submission_id: submissionId,
      message_id: messageId,
      in_reply_to: inReplyTo,
      reference_chain: [inReplyTo],
      from_email: adminEmail,
      to_email: submission.email,
      subject: finalSubject,
      body_text: finalReplyBody,
      direction: 'outbound',
      sent_by: user.id,
      metadata: {
        admin_email: user.email,
        sent_at: new Date().toISOString()
      }
    });

  if (insertError) {
    addSpanEvent(span, 'thread_insert_failed', { error: insertError });
  } else {
    addSpanEvent(span, 'thread_inserted');
  }

  // Update submission
  await supabase
    .from('contact_submissions')
    .update({
      last_admin_response_at: new Date().toISOString(),
      response_count: (submission.response_count || 0) + 1,
      status: 'in_progress'
    })
    .eq('id', submissionId);

  addSpanEvent(span, 'submission_updated');

  // Audit log
  await supabase
    .from('admin_audit_log')
    .insert({
      admin_user_id: user.id,
      target_user_id: user.id,
      action: 'send_contact_email_reply',
      details: {
        submission_id: submissionId,
        recipient: submission.email,
        subject: finalSubject
      }
    });

  addSpanEvent(span, 'audit_logged');

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

serve(createEdgeFunction({
  name: 'send-admin-email-reply',
  requireAuth: true,
  requiredRoles: ['superuser', 'admin', 'moderator'],
  corsHeaders,
  logRequests: true,
  logResponses: true,
}, handler));
