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

interface ExportOptions {
  include_reviews: boolean;
  include_lists: boolean;
  include_activity_log: boolean;
  include_preferences: boolean;
  format: 'json';
}

const handler = async (req: Request, { supabase, user, span, requestId }: EdgeFunctionContext) => {
  addSpanEvent(span, 'processing_export_request', { userId: user.id });

  // Additional rate limiting - max 1 export per hour
  const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();
  const { data: recentExports, error: rateLimitError } = await supabase
    .from('profile_audit_log')
    .select('created_at')
    .eq('user_id', user.id)
    .eq('action', 'data_exported')
    .gte('created_at', oneHourAgo)
    .limit(1);

  if (rateLimitError) {
    addSpanEvent(span, 'rate_limit_check_failed', { error: rateLimitError.message });
  }

  if (recentExports && recentExports.length > 0) {
    const nextAvailableAt = new Date(new Date(recentExports[0].created_at).getTime() + 60 * 60 * 1000).toISOString();
    addSpanEvent(span, 'rate_limit_exceeded', { nextAvailableAt });
    
    return new Response(
      JSON.stringify({
        success: false,
        error: 'Rate limited. You can export your data once per hour.',
        rate_limited: true,
        next_available_at: nextAvailableAt,
      }),
      { status: 429 }
    );
  }

  // Parse export options
  const body = await req.json();
  const options: ExportOptions = {
    include_reviews: body.include_reviews ?? true,
    include_lists: body.include_lists ?? true,
    include_activity_log: body.include_activity_log ?? true,
    include_preferences: body.include_preferences ?? true,
    format: 'json'
  };

  addSpanEvent(span, 'export_options_parsed', { options });

  // Fetch profile data
  const { data: profile, error: profileError } = await supabase
    .from('profiles')
    .select('username, display_name, bio, preferred_pronouns, personal_location, timezone, preferred_language, theme_preference, privacy_level, ride_count, coaster_count, park_count, review_count, reputation_score, created_at, updated_at')
    .eq('user_id', user.id)
    .single();

  if (profileError) {
    addSpanEvent(span, 'profile_fetch_failed', { error: profileError.message });
    throw new Error('Failed to fetch profile data');
  }

  // Fetch statistics
  const { count: photoCount } = await supabase
    .from('photos')
    .select('*', { count: 'exact', head: true })
    .eq('submitted_by', user.id);

  const { count: listCount } = await supabase
    .from('user_lists')
    .select('*', { count: 'exact', head: true })
    .eq('user_id', user.id);

  const { count: submissionCount } = await supabase
    .from('content_submissions')
    .select('*', { count: 'exact', head: true })
    .eq('user_id', user.id);

  const statistics = {
    ride_count: profile.ride_count || 0,
    coaster_count: profile.coaster_count || 0,
    park_count: profile.park_count || 0,
    review_count: profile.review_count || 0,
    reputation_score: profile.reputation_score || 0,
    photo_count: photoCount || 0,
    list_count: listCount || 0,
    submission_count: submissionCount || 0,
    account_created: profile.created_at,
    last_updated: profile.updated_at
  };

  // Fetch reviews if requested
  let reviews = [];
  if (options.include_reviews) {
    const { data: reviewsData, error: reviewsError } = await supabase
      .from('reviews')
      .select(`
        id,
        rating,
        review_text,
        created_at,
        rides(name),
        parks(name)
      `)
      .eq('user_id', user.id)
      .order('created_at', { ascending: false });

    if (!reviewsError && reviewsData) {
      reviews = reviewsData.map(r => ({
        id: r.id,
        rating: r.rating,
        review_text: r.review_text,
        ride_name: r.rides?.name,
        park_name: r.parks?.name,
        created_at: r.created_at
      }));
    }
  }

  // Fetch lists if requested
  let lists = [];
  if (options.include_lists) {
    const { data: listsData, error: listsError } = await supabase
      .from('user_lists')
      .select('id, name, description, is_public, created_at')
      .eq('user_id', user.id)
      .order('created_at', { ascending: false });

    if (!listsError && listsData) {
      lists = await Promise.all(
        listsData.map(async (list) => {
          const { count } = await supabase
            .from('user_list_items')
            .select('*', { count: 'exact', head: true })
            .eq('list_id', list.id);

          return {
            id: list.id,
            name: list.name,
            description: list.description,
            is_public: list.is_public,
            item_count: count || 0,
            created_at: list.created_at
          };
        })
      );
    }
  }

  // Fetch activity log if requested
  let activity_log = [];
  if (options.include_activity_log) {
    const { data: activityData, error: activityError } = await supabase
      .from('profile_audit_log')
      .select('id, action, changes, created_at, changed_by, ip_address_hash, user_agent')
      .eq('user_id', user.id)
      .order('created_at', { ascending: false })
      .limit(100);

    if (!activityError && activityData) {
      activity_log = activityData;
    }
  }

  // Fetch preferences if requested
  let preferences = {
    unit_preferences: null,
    accessibility_options: null,
    notification_preferences: null,
    privacy_settings: null
  };

  if (options.include_preferences) {
    const { data: prefsData } = await supabase
      .from('user_preferences')
      .select('unit_preferences, accessibility_options, notification_preferences, privacy_settings')
      .eq('user_id', user.id)
      .single();

    if (prefsData) {
      preferences = prefsData;
    }
  }

  // Build export data structure
  const exportData = {
    export_date: new Date().toISOString(),
    user_id: user.id,
    profile: {
      username: profile.username,
      display_name: profile.display_name,
      bio: profile.bio,
      preferred_pronouns: profile.preferred_pronouns,
      personal_location: profile.personal_location,
      timezone: profile.timezone,
      preferred_language: profile.preferred_language,
      theme_preference: profile.theme_preference,
      privacy_level: profile.privacy_level,
      created_at: profile.created_at,
      updated_at: profile.updated_at
    },
    statistics,
    reviews,
    lists,
    activity_log,
    preferences,
    metadata: {
      export_version: '1.0.0',
      data_retention_info: 'Your data is retained according to our privacy policy. You can request deletion at any time from your account settings.',
      instructions: 'This file contains all your personal data stored in ThrillWiki. You can use this for backup purposes or to migrate to another service. For questions, contact support@thrillwiki.com'
    }
  };

  // Log the export action
  await supabase.from('profile_audit_log').insert([{
    user_id: user.id,
    changed_by: user.id,
    action: 'data_exported',
    changes: {
      export_options: options,
      timestamp: new Date().toISOString(),
      data_size: JSON.stringify(exportData).length,
      requestId
    }
  }]);

  addSpanEvent(span, 'export_completed', { 
    dataSize: JSON.stringify(exportData).length 
  });

  return new Response(
    JSON.stringify({ 
      success: true, 
      data: exportData,
    }),
    { 
      headers: { 
        'Content-Disposition': `attachment; filename="thrillwiki-data-export-${new Date().toISOString().split('T')[0]}.json"`,
      } 
    }
  );
};

serve(createEdgeFunction({
  name: 'export-user-data',
  requireAuth: true,
  corsHeaders,
  enableTracing: true,
  logRequests: true,
  logResponses: true,
  rateLimitTier: 'strict', // 5 requests per minute
}, handler));
