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 { edgeLogger, startRequest, endRequest } from "../_shared/logger.ts";
import { createErrorResponse } from "../_shared/errorSanitizer.ts";

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

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

const handler = async (req: Request): Promise<Response> => {
  if (req.method === 'OPTIONS') {
    return new Response(null, { headers: corsHeaders });
  }

  const tracking = startRequest();

  try {
    const authHeader = req.headers.get('Authorization');
    if (!authHeader) {
      return createErrorResponse({ message: 'Unauthorized' }, 401, corsHeaders);
    }

    const supabase = createClient(
      Deno.env.get('SUPABASE_URL')!,
      Deno.env.get('SUPABASE_ANON_KEY')!,
      { global: { headers: { Authorization: authHeader } } }
    );

    const { data: { user }, error: userError } = await supabase.auth.getUser();
    if (userError || !user) {
      return createErrorResponse({ message: 'Unauthorized' }, 401, corsHeaders);
    }

    // Verify admin, moderator, or superuser role
    const { data: isSuperuser } = await supabase
      .rpc('has_role', { _user_id: user.id, _role: 'superuser' });
    const { data: isAdmin } = await supabase
      .rpc('has_role', { _user_id: user.id, _role: 'admin' });
    const { data: isModerator } = await supabase
      .rpc('has_role', { _user_id: user.id, _role: 'moderator' });

    if (!isSuperuser && !isAdmin && !isModerator) {
      edgeLogger.warn('Non-privileged user attempted email reply', { 
        requestId: tracking.requestId,
        userId: user.id 
      });
      return createErrorResponse({ message: 'Admin access required' }, 403, corsHeaders);
    }

    const body: AdminReplyRequest = await req.json();
    const { submissionId, replyBody, replySubject } = body;

    if (!submissionId || !replyBody) {
      return createErrorResponse({ message: 'Missing required fields' }, 400, corsHeaders);
    }

    if (replyBody.length < 10 || replyBody.length > 5000) {
      return createErrorResponse({ 
        message: 'Reply must be between 10 and 5000 characters' 
      }, 400, corsHeaders);
    }

    // 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) {
      return createErrorResponse({ message: 'Submission not found' }, 404, corsHeaders);
    }

    // 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) {
      return createErrorResponse({ 
        message: 'Rate limit exceeded. Max 10 replies per hour.' 
      }, 429, corsHeaders);
    }

    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;

    // 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();
      edgeLogger.error('ForwardEmail API error', { 
        requestId: tracking.requestId,
        status: forwardEmailResponse.status,
        error: errorText 
      });
      return createErrorResponse({ message: 'Failed to send email' }, 500, corsHeaders);
    }

    // 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) {
      edgeLogger.error('Failed to insert email thread', { 
        requestId: tracking.requestId,
        error: insertError 
      });
    }

    // 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);

    // 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
        }
      });

    edgeLogger.info('Admin email reply sent successfully', {
      requestId: tracking.requestId,
      submissionId,
      duration: endRequest(tracking)
    });

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

  } catch (error) {
    edgeLogger.error('Unexpected error in send-admin-email-reply', {
      requestId: tracking.requestId,
      error: error instanceof Error ? error.message : String(error)
    });
    return createErrorResponse(error, 500, corsHeaders);
  }
};

serve(handler);