import { serve } from 'https://deno.land/std@0.168.0/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.57.4';
import { sanitizeError } from '../_shared/errorSanitizer.ts';
import { edgeLogger, startRequest, endRequest } from '../_shared/logger.ts';

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

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

serve(async (req) => {
  const tracking = startRequest();
  
  // Handle CORS preflight requests
  if (req.method === 'OPTIONS') {
    return new Response(null, { 
      headers: { 
        ...corsHeaders,
        'X-Request-ID': tracking.requestId 
      } 
    });
  }

  try {
    const supabaseClient = createClient(
      Deno.env.get('SUPABASE_URL') ?? '',
      Deno.env.get('SUPABASE_ANON_KEY') ?? '',
      {
        global: {
          headers: { Authorization: req.headers.get('Authorization')! },
        },
      }
    );

    // Get authenticated user
    const {
      data: { user },
      error: authError,
    } = await supabaseClient.auth.getUser();

    if (authError || !user) {
      const duration = endRequest(tracking);
      edgeLogger.error('Authentication failed', { 
        action: 'export_auth',
        requestId: tracking.requestId,
        duration 
      });
      return new Response(
        JSON.stringify({ 
          error: 'Unauthorized', 
          success: false,
          requestId: tracking.requestId 
        }),
        { 
          status: 401, 
          headers: { 
            ...corsHeaders, 
            'Content-Type': 'application/json',
            'X-Request-ID': tracking.requestId 
          } 
        }
      );
    }

    edgeLogger.info('Processing export request', { 
      action: 'export_start', 
      requestId: tracking.requestId,
      userId: user.id 
    });

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

    if (rateLimitError) {
      console.error('[Export] Rate limit check failed:', rateLimitError);
    }

    if (recentExports && recentExports.length > 0) {
      const duration = endRequest(tracking);
      const nextAvailableAt = new Date(new Date(recentExports[0].created_at).getTime() + 60 * 60 * 1000).toISOString();
      edgeLogger.warn('Rate limit exceeded for export', { 
        action: 'export_rate_limit',
        requestId: tracking.requestId,
        userId: user.id,
        duration,
        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,
          requestId: tracking.requestId
        }),
        { 
          status: 429, 
          headers: { 
            ...corsHeaders, 
            'Content-Type': 'application/json',
            'X-Request-ID': tracking.requestId 
          } 
        }
      );
    }

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

    edgeLogger.info('Export options', { 
      action: 'export_options', 
      requestId: tracking.requestId,
      userId: user.id 
    });

    // Fetch profile data
    const { data: profile, error: profileError } = await supabaseClient
      .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) {
      edgeLogger.error('Profile fetch failed', { 
        action: 'export_profile',
        requestId: tracking.requestId,
        userId: user.id 
      });
      throw new Error('Failed to fetch profile data');
    }

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

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

    const { count: submissionCount } = await supabaseClient
      .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 supabaseClient
        .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 supabaseClient
        .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 supabaseClient
              .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 supabaseClient
        .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 supabaseClient
        .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 supabaseClient.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: tracking.requestId
      }
    }]);

    const duration = endRequest(tracking);
    edgeLogger.info('Export completed successfully', { 
      action: 'export_complete', 
      requestId: tracking.requestId,
      traceId: tracking.traceId,
      userId: user.id,
      duration,
      dataSize: JSON.stringify(exportData).length 
    });

    return new Response(
      JSON.stringify({ 
        success: true, 
        data: exportData,
        requestId: tracking.requestId 
      }),
      { 
        status: 200, 
        headers: { 
          ...corsHeaders, 
          'Content-Type': 'application/json',
          'Content-Disposition': `attachment; filename="thrillwiki-data-export-${new Date().toISOString().split('T')[0]}.json"`,
          'X-Request-ID': tracking.requestId
        } 
      }
    );

  } catch (error) {
    const duration = endRequest(tracking);
    edgeLogger.error('Export error', { 
      action: 'export_error', 
      requestId: tracking.requestId,
      duration,
      error: error instanceof Error ? error.message : String(error) 
    });
    const sanitized = sanitizeError(error, 'export-user-data');
    return new Response(
      JSON.stringify({ 
        ...sanitized,
        success: false,
        requestId: tracking.requestId 
      }),
      { 
        status: 500, 
        headers: { 
          ...corsHeaders, 
          'Content-Type': 'application/json',
          'X-Request-ID': tracking.requestId 
        } 
      }
    );
  }
});
