export const prerender = false;

import type { APIRoute } from 'astro';
import { supabase } from '../../../lib/supabase';
import { requireAuth, getClientIP, checkRateLimit, createAuthResponse } from '../../../lib/auth';
import { validateRequest } from '../../../lib/validation';
import { logUserActivity, logSecurityEvent } from '../../../lib/logger';
import { z } from 'zod';

// Validation schemas
const userDataRequestSchema = z.object({
  request_type: z.enum(['export', 'delete', 'portability']),
  user_email: z.string().email().optional(),
  confirmation: z.boolean().optional()
});

// User data export endpoint
export const GET: APIRoute = async ({ request }) => {
  try {
    // Rate limiting
    const clientIP = getClientIP(request);
    if (!checkRateLimit(`gdpr-export:${clientIP}`, 2, 300000)) { // 2 requests per 5 minutes
      return createAuthResponse({ error: 'Rate limit exceeded for data export requests' }, 429);
    }

    // Require authentication
    const auth = await requireAuth(request);
    
    // Log data export request
    logUserActivity({
      action: 'gdpr_data_export_requested',
      userId: auth.user.id,
      ipAddress: clientIP,
      userAgent: request.headers.get('User-Agent') || undefined,
      details: { requestType: 'export' }
    });

    // Collect all user data
    const userData = await collectUserData(auth.user.id);
    
    // Log successful export
    logUserActivity({
      action: 'gdpr_data_export_completed',
      userId: auth.user.id,
      ipAddress: clientIP,
      details: { dataSize: JSON.stringify(userData).length }
    });

    return createAuthResponse({
      success: true,
      data: userData,
      exported_at: new Date().toISOString(),
      user_id: auth.user.id,
      notice: 'This export contains all personal data we have stored about you. You have the right to correct, update, or delete this information.'
    });

  } catch (error) {
    console.error('Error exporting user data:', error);
    return createAuthResponse({ 
      error: 'Failed to export user data'
    }, 500);
  }
};

// User data deletion endpoint
export const DELETE: APIRoute = async ({ request }) => {
  try {
    // Rate limiting
    const clientIP = getClientIP(request);
    if (!checkRateLimit(`gdpr-delete:${clientIP}`, 1, 86400000)) { // 1 request per day
      return createAuthResponse({ error: 'Rate limit exceeded for data deletion requests' }, 429);
    }

    // Require authentication
    const auth = await requireAuth(request);
    
    const body = await request.json();
    const validation = validateRequest(userDataRequestSchema, body);
    if (!validation.success) {
      return createAuthResponse({ 
        error: 'Invalid request',
        details: validation.error
      }, 400);
    }

    const { confirmation } = validation.data;
    
    if (!confirmation) {
      return createAuthResponse({ 
        error: 'Deletion confirmation required',
        notice: 'You must explicitly confirm that you want to delete all your data. This action cannot be undone.'
      }, 400);
    }

    // Log deletion request
    logUserActivity({
      action: 'gdpr_data_deletion_requested',
      userId: auth.user.id,
      ipAddress: clientIP,
      userAgent: request.headers.get('User-Agent') || undefined,
      details: { confirmation: true }
    });

    // Check for active events or pending transactions
    const { data: activeEvents } = await supabase
      .from('events')
      .select('id, title, start_time')
      .eq('created_by', auth.user.id)
      .gt('start_time', new Date().toISOString());

    const { data: pendingTickets } = await supabase
      .from('tickets')
      .select('id, event_id')
      .eq('purchaser_email', auth.user.email)
      .eq('status', 'valid')
      .neq('checked_in', true);

    if (activeEvents && activeEvents.length > 0) {
      return createAuthResponse({ 
        error: 'Cannot delete account with active events',
        details: 'You have active events that are scheduled for the future. Please cancel or complete these events before deleting your account.',
        active_events: activeEvents
      }, 400);
    }

    if (pendingTickets && pendingTickets.length > 0) {
      return createAuthResponse({ 
        error: 'Cannot delete account with valid tickets',
        details: 'You have valid tickets for upcoming events. Please use or transfer these tickets before deleting your account.',
        ticket_count: pendingTickets.length
      }, 400);
    }

    // Perform data deletion
    await deleteUserData(auth.user.id, auth.user.email!);
    
    // Log successful deletion
    logUserActivity({
      action: 'gdpr_data_deletion_completed',
      userId: auth.user.id,
      ipAddress: clientIP,
      details: { deletedAt: new Date().toISOString() }
    });

    // Sign out the user
    await supabase.auth.signOut();

    return createAuthResponse({
      success: true,
      message: 'Your account and all associated data have been permanently deleted.',
      deleted_at: new Date().toISOString()
    });

  } catch (error) {
    console.error('Error deleting user data:', error);
    return createAuthResponse({ 
      error: 'Failed to delete user data'
    }, 500);
  }
};

// Data portability endpoint (structured data for transfer)
export const POST: APIRoute = async ({ request }) => {
  try {
    // Rate limiting
    const clientIP = getClientIP(request);
    if (!checkRateLimit(`gdpr-portability:${clientIP}`, 3, 3600000)) { // 3 requests per hour
      return createAuthResponse({ error: 'Rate limit exceeded for data portability requests' }, 429);
    }

    // Require authentication
    const auth = await requireAuth(request);
    
    const body = await request.json();
    const validation = validateRequest(userDataRequestSchema, body);
    if (!validation.success) {
      return createAuthResponse({ 
        error: 'Invalid request',
        details: validation.error
      }, 400);
    }

    // Log portability request
    logUserActivity({
      action: 'gdpr_data_portability_requested',
      userId: auth.user.id,
      ipAddress: clientIP,
      userAgent: request.headers.get('User-Agent') || undefined
    });

    // Collect structured data for portability
    const portableData = await collectPortableData(auth.user.id);
    
    return createAuthResponse({
      success: true,
      data: portableData,
      format: 'json',
      exported_at: new Date().toISOString(),
      notice: 'This data is formatted for easy import into other systems. The format complies with GDPR portability requirements.'
    });

  } catch (error) {
    console.error('Error creating portable data:', error);
    return createAuthResponse({ 
      error: 'Failed to create portable data'
    }, 500);
  }
};

// Helper function to collect all user data
async function collectUserData(userId: string) {
  const userData: any = {
    user_profile: null,
    organizations: [],
    events: [],
    tickets: [],
    purchase_attempts: [],
    audit_logs: [],
    collected_at: new Date().toISOString()
  };

  try {
    // Get user profile
    const { data: user } = await supabase
      .from('users')
      .select('*')
      .eq('id', userId)
      .single();
    userData.user_profile = user;

    // Get organizations
    const { data: organizations } = await supabase
      .from('organizations')
      .select('*')
      .eq('id', user?.organization_id);
    userData.organizations = organizations || [];

    // Get events created by user
    const { data: events } = await supabase
      .from('events')
      .select('*')
      .eq('created_by', userId);
    userData.events = events || [];

    // Get tickets purchased by user
    const { data: tickets } = await supabase
      .from('tickets')
      .select('*')
      .eq('purchaser_email', user?.email);
    userData.tickets = tickets || [];

    // Get purchase attempts
    const { data: purchases } = await supabase
      .from('purchase_attempts')
      .select('*')
      .eq('purchaser_email', user?.email);
    userData.purchase_attempts = purchases || [];

    // Get audit logs (admin actions by this user)
    const { data: auditLogs } = await supabase
      .from('audit_logs')
      .select('*')
      .eq('user_id', userId)
      .order('created_at', { ascending: false })
      .limit(100); // Limit to recent 100 entries
    userData.audit_logs = auditLogs || [];

  } catch (error) {
    console.error('Error collecting user data:', error);
    throw error;
  }

  return userData;
}

// Helper function to collect portable data (structured for transfer)
async function collectPortableData(userId: string) {
  const { data: user } = await supabase
    .from('users')
    .select('*')
    .eq('id', userId)
    .single();

  const portableData = {
    profile: {
      name: user?.name,
      email: user?.email,
      created_at: user?.created_at,
      role: user?.role
    },
    events_created: [],
    tickets_purchased: [],
    purchase_history: []
  };

  // Get events in portable format
  const { data: events } = await supabase
    .from('events')
    .select('title, description, venue, start_time, end_time, created_at')
    .eq('created_by', userId);
  
  portableData.events_created = events?.map(event => ({
    title: event.title,
    description: event.description,
    venue: event.venue,
    start_time: event.start_time,
    end_time: event.end_time,
    created_at: event.created_at
  })) || [];

  // Get tickets in portable format
  const { data: tickets } = await supabase
    .from('tickets')
    .select(`
      price,
      status,
      checked_in,
      created_at,
      events (title, venue, start_time)
    `)
    .eq('purchaser_email', user?.email);
  
  portableData.tickets_purchased = tickets?.map(ticket => ({
    event_title: ticket.events?.title,
    event_venue: ticket.events?.venue,
    event_date: ticket.events?.start_time,
    price_paid: ticket.price,
    status: ticket.status,
    attended: ticket.checked_in,
    purchased_at: ticket.created_at
  })) || [];

  return portableData;
}

// Helper function to delete user data
async function deleteUserData(userId: string, userEmail: string) {
  try {
    // Note: Be careful with deletions - some data may need to be retained for legal/accounting purposes
    
    // Delete in reverse order of dependencies
    
    // Delete audit logs
    await supabase
      .from('audit_logs')
      .delete()
      .eq('user_id', userId);

    // Anonymize tickets instead of deleting (for event organizer records)
    await supabase
      .from('tickets')
      .update({
        purchaser_email: `deleted-user-${Date.now()}@anonymized.local`,
        purchaser_name: 'Deleted User'
      })
      .eq('purchaser_email', userEmail);

    // Anonymize purchase attempts
    await supabase
      .from('purchase_attempts')
      .update({
        purchaser_email: `deleted-user-${Date.now()}@anonymized.local`,
        purchaser_name: 'Deleted User'
      })
      .eq('purchaser_email', userEmail);

    // Delete events created by user (only if no tickets sold)
    const { data: userEvents } = await supabase
      .from('events')
      .select('id')
      .eq('created_by', userId);

    if (userEvents) {
      for (const event of userEvents) {
        const { data: eventTickets } = await supabase
          .from('tickets')
          .select('id')
          .eq('event_id', event.id)
          .limit(1);

        if (!eventTickets || eventTickets.length === 0) {
          // Safe to delete event with no tickets
          await supabase
            .from('events')
            .delete()
            .eq('id', event.id);
        } else {
          // Anonymize event creator
          await supabase
            .from('events')
            .update({ created_by: null })
            .eq('id', event.id);
        }
      }
    }

    // Delete user profile
    await supabase
      .from('users')
      .delete()
      .eq('id', userId);

    // Delete from Supabase Auth
    // Note: This would typically be done through the admin API
    // For now, we'll just sign out the user
    
  } catch (error) {
    console.error('Error deleting user data:', error);
    throw error;
  }
}