import { supabase } from '@/db/supabase';
import type {
  AccountDeletionRequest,
  AuditLog,
  ConsentFormData,
  DataExportRequest,
  UserConsent,
} from '@/types/gdpr';

// Kullanıcı IP adresini al (client-side)
const getClientIP = async (): Promise<string | undefined> => {
  try {
    const response = await fetch('https://api.ipify.org?format=json');
    const data = await response.json();
    return data.ip;
  } catch (error) {
    console.error('IP adresi alınamadı:', error);
    return undefined;
  }
};

// User Agent bilgisini al
const getUserAgent = (): string => {
  return navigator.userAgent;
};

// Consent API
export const consentApi = {
  // Kullanıcının onaylarını kaydet
  async recordConsent(
    userId: string,
    consents: ConsentFormData,
    version: string = '1.0'
  ): Promise<void> {
    const ip = await getClientIP();
    const userAgent = getUserAgent();

    const consentRecords = Object.entries(consents).map(([type, given]) => ({
      user_id: userId,
      consent_type: type,
      consent_given: given,
      ip_address: ip,
      user_agent: userAgent,
      consent_version: version,
    }));

    const { error } = await supabase.from('user_consents').insert(consentRecords as any);

    if (error) throw error;
  },

  // Kullanıcının onaylarını güncelle
  async updateConsent(
    userId: string,
    consentType: string,
    consentGiven: boolean,
    version: string = '1.0'
  ): Promise<void> {
    const ip = await getClientIP();
    const userAgent = getUserAgent();

    const { error } = await supabase.from('user_consents').insert({
      user_id: userId,
      consent_type: consentType,
      consent_given: consentGiven,
      ip_address: ip,
      user_agent: userAgent,
      consent_version: version,
    } as any);

    if (error) throw error;
  },

  // Kullanıcının onaylarını getir
  async getUserConsents(userId: string): Promise<UserConsent[]> {
    const { data, error } = await supabase
      .from('user_consents')
      .select('*')
      .eq('user_id', userId)
      .order('created_at', { ascending: false });

    if (error) throw error;
    return data || [];
  },

  // En son onayları getir (her tip için)
  async getLatestConsents(userId: string): Promise<Record<string, UserConsent>> {
    const { data, error } = await supabase
      .from('user_consents')
      .select('*')
      .eq('user_id', userId)
      .order('created_at', { ascending: false });

    if (error) throw error;

    // Her consent type için en son kaydı al
    const latestConsents: Record<string, UserConsent> = {};
    (data as any)?.forEach((consent: any) => {
      if (!latestConsents[consent.consent_type]) {
        latestConsents[consent.consent_type] = consent;
      }
    });

    return latestConsents;
  },
};

// Audit Log API
export const auditLogApi = {
  // Audit log kaydı oluştur
  async logAction(
    action: AuditLog['action'],
    resourceType: string,
    resourceId?: string,
    oldData?: Record<string, any>,
    newData?: Record<string, any>
  ): Promise<void> {
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) return;

    const ip = await getClientIP();
    const userAgent = getUserAgent();

    const { error } = await supabase.from('audit_logs').insert({
      user_id: user.id,
      action,
      resource_type: resourceType,
      resource_id: resourceId,
      old_data: oldData,
      new_data: newData,
      ip_address: ip,
      user_agent: userAgent,
    } as any);

    if (error) console.error('Audit log kaydedilemedi:', error);
  },

  // Kullanıcının audit loglarını getir
  async getUserLogs(userId: string, limit = 50): Promise<AuditLog[]> {
    const { data, error } = await supabase
      .from('audit_logs')
      .select('*')
      .eq('user_id', userId)
      .order('created_at', { ascending: false })
      .limit(limit);

    if (error) throw error;
    return data || [];
  },

  // Belirli bir kaynağın audit loglarını getir
  async getResourceLogs(resourceType: string, resourceId: string): Promise<AuditLog[]> {
    const { data, error } = await supabase
      .from('audit_logs')
      .select('*')
      .eq('resource_type', resourceType)
      .eq('resource_id', resourceId)
      .order('created_at', { ascending: false });

    if (error) throw error;
    return data || [];
  },
};

// Data Export API
export const dataExportApi = {
  // Veri dışa aktarma talebi oluştur
  async requestExport(): Promise<DataExportRequest> {
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı oturumu bulunamadı');

    const { data, error } = await supabase
      .from('data_export_requests')
      .insert({
        user_id: user.id,
        status: 'pending',
      } as any)
      .select()
      .single();

    if (error) throw error;

    // Edge function'ı tetikle (arka planda veri dışa aktarımı yapacak)
    supabase.functions
      .invoke('process-data-export', {
        body: { requestId: (data as any).id },
      })
      .catch((err) => console.error('Veri dışa aktarma işlemi başlatılamadı:', err));

    return data as any;
  },

  // Kullanıcının dışa aktarma taleplerini getir
  async getExportRequests(): Promise<DataExportRequest[]> {
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı oturumu bulunamadı');

    const { data, error } = await supabase
      .from('data_export_requests')
      .select('*')
      .eq('user_id', user.id)
      .order('requested_at', { ascending: false });

    if (error) throw error;
    return data || [];
  },

  // Dışa aktarılan veriyi indir
  async downloadExport(requestId: string): Promise<Blob> {
    const { data, error } = await supabase
      .from('data_export_requests')
      .select('export_data')
      .eq('id', requestId)
      .single();

    if (error) throw error;
    if (!(data as any).export_data) throw new Error('Dışa aktarılan veri bulunamadı');

    // JSON verisini Blob'a çevir
    const blob = new Blob([JSON.stringify((data as any).export_data, null, 2)], {
      type: 'application/json',
    });

    return blob;
  },
};

// Account Deletion API
export const accountDeletionApi = {
  // Hesap silme talebi oluştur
  async requestDeletion(reason?: string): Promise<AccountDeletionRequest> {
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı oturumu bulunamadı');

    // 30 gün sonrası için silme tarihi belirle
    const scheduledDeletion = new Date();
    scheduledDeletion.setDate(scheduledDeletion.getDate() + 30);

    const { data, error } = await supabase
      .from('account_deletion_requests')
      .insert({
        user_id: user.id,
        reason,
        status: 'pending',
        scheduled_deletion_at: scheduledDeletion.toISOString(),
      } as any)
      .select()
      .single();

    if (error) throw error;

    // Audit log kaydet
    await auditLogApi.logAction('delete', 'account_deletion_request', (data as any).id);

    return data as any;
  },

  // Hesap silme talebini iptal et
  async cancelDeletion(requestId: string): Promise<void> {
    // @ts-ignore - GDPR tables are dynamically created
    const result = await supabase
      .from('account_deletion_requests')
      // @ts-ignore
      .update({
        status: 'cancelled',
        updated_at: new Date().toISOString(),
      })
      .eq('id', requestId);
    
    const { error } = result;

    if (error) throw error;

    // Audit log kaydet
    await auditLogApi.logAction('update', 'account_deletion_request', requestId);
  },

  // Kullanıcının silme taleplerini getir
  async getDeletionRequests(): Promise<AccountDeletionRequest[]> {
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı oturumu bulunamadı');

    const { data, error } = await supabase
      .from('account_deletion_requests')
      .select('*')
      .eq('user_id', user.id)
      .order('requested_at', { ascending: false });

    if (error) throw error;
    return data || [];
  },

  // Hesabı hemen sil (admin veya kullanıcı onayı ile)
  async deleteAccountNow(): Promise<void> {
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı oturumu bulunamadı');

    // Verileri anonimleştir
    // @ts-ignore - GDPR RPC function
    const result = await supabase.rpc('anonymize_user_data', {
      p_user_id: user.id,
    });
    const { error: anonymizeError } = result;

    if (anonymizeError) throw anonymizeError;

    // Auth kullanıcısını sil
    const { error: deleteError } = await supabase.auth.admin.deleteUser(user.id);

    if (deleteError) throw deleteError;
  },
};

// GDPR Utilities
export const gdprUtils = {
  // Kullanıcının tüm verilerini dışa aktar (client-side)
  async exportAllUserData(): Promise<Record<string, any>> {
    const {
      data: { user },
    } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı oturumu bulunamadı');

    const { data, error } = await supabase.rpc('export_user_data', {
      p_user_id: user.id,
    } as any);

    if (error) throw error;
    return data;
  },

  // Consent durumunu kontrol et
  async checkConsentStatus(userId: string): Promise<{
    hasTermsConsent: boolean;
    hasPrivacyConsent: boolean;
    hasMarketingConsent: boolean;
    hasAnalyticsConsent: boolean;
  }> {
    const latestConsents = await consentApi.getLatestConsents(userId);

    return {
      hasTermsConsent: latestConsents.terms?.consent_given || false,
      hasPrivacyConsent: latestConsents.privacy?.consent_given || false,
      hasMarketingConsent: latestConsents.marketing?.consent_given || false,
      hasAnalyticsConsent: latestConsents.analytics?.consent_given || false,
    };
  },
};
