import type { PageSEO, SEOSettings, URLRedirect } from '@/types/seo';
import { supabase } from './supabase';

/**
 * GÜVENLİK YARDIMCILARI (Input Validation & Sanitization)
 */

// Basit Rate Limiter
const rateLimits = new Map<string, number>();
const checkRateLimit = (key: string, cooldown = 1000) => {
  const now = Date.now();
  const lastCall = rateLimits.get(key) || 0;
  if (now - lastCall < cooldown) {
    throw new Error('Çok sık işlem yapıyorsunuz. Lütfen biraz bekleyin.');
  }
  rateLimits.set(key, now);
};

// Gelişmiş Rate Limiter (Saatlik limit için)
interface RateLimitEntry {
  count: number;
  resetTime: number;
}

const hourlyRateLimits = new Map<string, RateLimitEntry>();

const checkHourlyRateLimit = (key: string, maxRequests: number, windowMs: number = 3600000) => {
  const now = Date.now();
  const entry = hourlyRateLimits.get(key);

  if (!entry || now > entry.resetTime) {
    // Yeni pencere başlat
    hourlyRateLimits.set(key, {
      count: 1,
      resetTime: now + windowMs
    });
    return;
  }

  if (entry.count >= maxRequests) {
    const remainingTime = Math.ceil((entry.resetTime - now) / 60000); // dakika cinsinden
    throw new Error(`Saatlik limit aşıldı. ${remainingTime} dakika sonra tekrar deneyin.`);
  }

  entry.count++;
  hourlyRateLimits.set(key, entry);
};

// Doğrulayıcı Oluşturucu
interface ValidationRules {
  min?: number;
  max?: number;
  required?: boolean;
  pattern?: RegExp;
  sanitize?: boolean;
}

type ValidatorFunction = (value: unknown, fieldName: string) => string | number | boolean | null | undefined;

const createValidator = (rules: ValidationRules): ValidatorFunction => {
  return (value: unknown, fieldName: string): string | number | boolean | null | undefined => {
    let sanitizedValue: string | number | boolean | null | undefined = value as string | number | boolean | null | undefined;

    if (rules.required && (value === undefined || value === null || value === '')) {
      throw new Error(`${fieldName} alanı zorunludur.`);
    }

    if (value === undefined || value === null) return value;

    if (typeof value === 'string') {
      sanitizedValue = value.trim();
      
      if (rules.sanitize) {
        // PostgREST özel karakterlerini ve SQL injection risklerini temizle
        sanitizedValue = (sanitizedValue as string)
          .replace(/[(),.]/g, '')
          .replace(/[%_]/g, '\\$&');
      }

      if (rules.min !== undefined && (sanitizedValue as string).length < rules.min) {
        throw new Error(`${fieldName} en az ${rules.min} karakter olmalıdır.`);
      }

      if (rules.max !== undefined && (sanitizedValue as string).length > rules.max) {
        throw new Error(`${fieldName} en fazla ${rules.max} karakter olabilir.`);
      }

      if (rules.pattern && !rules.pattern.test(sanitizedValue as string)) {
        throw new Error(`${fieldName} formatı geçersiz.`);
      }
    }

    return sanitizedValue;
  };
};

// Hata Yakalama Sarmalayıcısı
const safeExecute = async <T>(fn: () => Promise<T>, defaultError = 'Bir hata oluştu.'): Promise<T> => {
  try {
    return await fn();
  } catch (error) {
    console.error('[API Safe Execution Error]:', error);
    throw new Error(error instanceof Error ? error.message : defaultError);
  }
};

// Ortak Doğrulayıcılar
const validators = {
  searchQuery: createValidator({ min: 2, max: 100, sanitize: true, required: true }),
  city: createValidator({ min: 2, max: 50, sanitize: true, required: true }),
  country: createValidator({ min: 2, max: 50, sanitize: true, required: true }),
  type: createValidator({ min: 2, max: 50, sanitize: true, required: true }),
  uuid: createValidator({ pattern: /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i, required: true }),
  tripTitle: createValidator({ min: 3, max: 200, required: true }),
  tripDescription: createValidator({ min: 0, max: 2000, required: false }),
  destination: createValidator({ min: 2, max: 100, required: false }),
};

// Trip Data Interface
interface TripUpdateData {
  title?: string;
  description?: string;
  destination?: string;
  start_date?: string;
  end_date?: string;
  cover_image?: string;
  is_public?: boolean;
  interests?: string[];
  number_of_travelers?: number;
  start_location_type?: string;
  start_location_name?: string;
  start_lat?: number;
  start_lng?: number;
  has_balloon?: boolean;
  balloon_day_id?: string;
}

// Trip Validation Helper
const validateTripData = (trip: TripUpdateData) => {
  // Zorunlu alanlar
  const title = trip.title ? validators.tripTitle(trip.title, 'Seyahat başlığı') as string : undefined;
  
  // Opsiyonel alanlar
  const description = trip.description ? validators.tripDescription(trip.description, 'Açıklama') as string | undefined : undefined;
  const destination = trip.destination ? validators.destination(trip.destination, 'Hedef') as string | undefined : undefined;

  // Tarih validasyonu
  if (trip.start_date && trip.end_date) {
    const startDate = new Date(trip.start_date);
    const endDate = new Date(trip.end_date);
    
    if (isNaN(startDate.getTime())) {
      throw new Error('Başlangıç tarihi geçersiz.');
    }
    
    if (isNaN(endDate.getTime())) {
      throw new Error('Bitiş tarihi geçersiz.');
    }
    
    if (endDate < startDate) {
      throw new Error('Bitiş tarihi başlangıç tarihinden önce olamaz.');
    }

    // Maksimum 365 günlük seyahat
    const daysDiff = Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24));
    if (daysDiff > 365) {
      throw new Error('Seyahat süresi en fazla 365 gün olabilir.');
    }
  }

  // Konum validasyonu
  if (trip.start_lat !== undefined || trip.start_lng !== undefined) {
    if (typeof trip.start_lat !== 'number' || typeof trip.start_lng !== 'number') {
      throw new Error('Konum bilgileri geçersiz.');
    }
    
    if (trip.start_lat < -90 || trip.start_lat > 90) {
      throw new Error('Enlem değeri -90 ile 90 arasında olmalıdır.');
    }
    
    if (trip.start_lng < -180 || trip.start_lng > 180) {
      throw new Error('Boylam değeri -180 ile 180 arasında olmalıdır.');
    }
  }

  // İlgi alanları validasyonu
  if (trip.interests && Array.isArray(trip.interests)) {
    if (trip.interests.length > 20) {
      throw new Error('En fazla 20 ilgi alanı seçebilirsiniz.');
    }
    
    for (const interest of trip.interests) {
      if (typeof interest !== 'string' || interest.length > 50) {
        throw new Error('İlgi alanı formatı geçersiz.');
      }
    }
  }

  return {
    title,
    description,
    destination,
  };
};

// Security Audit Logger
const logSecurityEvent = (event: string, userId: string | null, details: Record<string, unknown>) => {
  const timestamp = new Date().toISOString();
  console.log(`[SECURITY AUDIT] ${timestamp} | Event: ${event} | User: ${userId || 'anonymous'} | Details:`, details);
};


// SEO API
export const seoApi = {
  // Global SEO ayarlarını getir
  async getSettings(): Promise<SEOSettings | null> {
    const { data, error } = await supabase
      .from('seo_settings')
      .select('*')
      .maybeSingle();

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

  // Global SEO ayarlarını güncelle
  async updateSettings(settings: Partial<SEOSettings>): Promise<SEOSettings> {
    const { data: existing } = await supabase
      .from('seo_settings')
      .select('id')
      .maybeSingle();

    let result;
    if (existing) {
      const { data, error } = await supabase
        .from('seo_settings')
        .update({ ...settings, updated_at: new Date().toISOString() })
        .eq('id', existing.id)
        .select()
        .single();

      if (error) throw error;
      result = data;
    } else {
      const { data, error } = await supabase
        .from('seo_settings')
        .insert([settings])
        .select()
        .single();

      if (error) throw error;
      result = data;
    }

    // Eğer site_name güncelleniyorsa, site_settings'i de güncelle
    if (settings.site_name) {
      try {
        const { data: siteExisting } = await supabase
          .from('site_settings')
          .select('id')
          .eq('key', 'site_name')
          .maybeSingle();

        if (siteExisting) {
          await supabase.from('site_settings').update({ value: settings.site_name }).eq('key', 'site_name');
        } else {
          await supabase.from('site_settings').insert({ key: 'site_name', value: settings.site_name });
        }
      } catch (e) {
        console.error('Site settings sync error:', e);
      }
    }

    return result;
  },

  // Sayfa SEO bilgilerini getir
  async getPageSEO(pagePath: string): Promise<PageSEO | null> {
    const { data, error } = await supabase
      .from('page_seo')
      .select('*')
      .eq('page_path', pagePath)
      .maybeSingle();

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

  // Tüm sayfa SEO bilgilerini getir
  async getAllPageSEO(): Promise<PageSEO[]> {
    const { data, error } = await supabase
      .from('page_seo')
      .select('*')
      .order('page_path', { ascending: true });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Sayfa SEO bilgilerini oluştur
  async createPageSEO(pageSEO: Omit<PageSEO, 'id' | 'created_at' | 'updated_at'>): Promise<PageSEO> {
    const { data, error } = await supabase
      .from('page_seo')
      .insert([pageSEO])
      .select()
      .single();

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

  // Sayfa SEO bilgilerini güncelle
  async updatePageSEO(id: string, updates: Partial<PageSEO>): Promise<PageSEO> {
    const { data, error } = await supabase
      .from('page_seo')
      .update({ ...updates, updated_at: new Date().toISOString() })
      .eq('id', id)
      .select()
      .single();

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

  // Sayfa SEO bilgilerini sil
  async deletePageSEO(id: string): Promise<void> {
    const { error } = await supabase
      .from('page_seo')
      .delete()
      .eq('id', id);

    if (error) throw error;
  },

  // URL yönlendirmelerini getir
  async getRedirects(): Promise<URLRedirect[]> {
    const { data, error } = await supabase
      .from('url_redirects')
      .select('*')
      .order('created_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Aktif yönlendirmeleri getir
  async getActiveRedirects(): Promise<URLRedirect[]> {
    const { data, error } = await supabase
      .from('url_redirects')
      .select('*')
      .eq('is_active', true)
      .order('created_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Belirli bir path için yönlendirme getir
  async getRedirectByPath(fromPath: string): Promise<URLRedirect | null> {
    const { data, error } = await supabase
      .from('url_redirects')
      .select('*')
      .eq('from_path', fromPath)
      .eq('is_active', true)
      .maybeSingle();

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

  // Yönlendirme oluştur
  async createRedirect(redirect: Omit<URLRedirect, 'id' | 'created_at' | 'updated_at'>): Promise<URLRedirect> {
    const { data, error } = await supabase
      .from('url_redirects')
      .insert([redirect])
      .select()
      .single();

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

  // Yönlendirme güncelle
  async updateRedirect(id: string, updates: Partial<URLRedirect>): Promise<URLRedirect> {
    const { data, error } = await supabase
      .from('url_redirects')
      .update({ ...updates, updated_at: new Date().toISOString() })
      .eq('id', id)
      .select()
      .single();

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

  // Yönlendirme sil
  async deleteRedirect(id: string): Promise<void> {
    const { error } = await supabase
      .from('url_redirects')
      .delete()
      .eq('id', id);

    if (error) throw error;
  },
};

/**
 * GÜVENLİ SEO API
 */
export const seoApiSafe = {
  ...seoApi,

  // Sayfa SEO bilgilerini getir (GÜVENLİ)
  async getPageSEO(pagePath: string) {
    return safeExecute(async () => {
      const pathValidator = createValidator({ min: 1, max: 255, sanitize: false });
      const sanitizedPath = pathValidator(pagePath, 'Sayfa yolu') as string;
      return await seoApi.getPageSEO(sanitizedPath);
    }, 'Sayfa SEO bilgileri getirilirken bir hata oluştu.');
  },

  // Belirli bir path için yönlendirme getir (GÜVENLİ)
  async getRedirectByPath(fromPath: string) {
    return safeExecute(async () => {
      const pathValidator = createValidator({ min: 1, max: 255, sanitize: false });
      const sanitizedPath = pathValidator(fromPath, 'Yönlendirme yolu') as string;
      return await seoApi.getRedirectByPath(sanitizedPath);
    }, 'Yönlendirme bilgisi getirilirken bir hata oluştu.');
  }
};


// Places API
export const placesApi = {
  // Tüm yerleri getir (pagination ile)
  async getAll(page = 1, limit = 50) {
    const from = (page - 1) * limit;
    const to = from + limit - 1;

    const { data, error, count } = await supabase
      .from('places')
      .select('*', { count: 'exact' })
      .order('created_at', { ascending: false })
      .range(from, to);

    if (error) throw error;

    return {
      places: Array.isArray(data) ? data : [],
      total: count || 0,
      page,
      totalPages: Math.ceil((count || 0) / limit),
      hasMore: (count || 0) > to + 1,
    };
  },

  // Şehre göre yerleri getir
  async getByCity(city: string) {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .ilike('city', `%${city}%`)
      .order('rating', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Ülkeye göre yerleri getir
  async getByCountry(country: string) {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .ilike('country', `%${country}%`)
      .order('rating', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Türe göre yerleri getir
  async getByType(type: string) {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .ilike('type', `%${type}%`)
      .order('rating', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Arama yap
  async search(query: string) {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .or(`name.ilike.%${query}%,city.ilike.%${query}%,country.ilike.%${query}%,description.ilike.%${query}%`)
      .order('rating', { ascending: false })
      .limit(20);

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // ID'ye göre yer getir
  async getById(id: string) {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .eq('id', id)
      .maybeSingle();

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

  // Popüler yerleri getir (rating'e göre)
  async getPopular(limit: number = 12) {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .not('rating', 'is', null)
      .order('rating', { ascending: false })
      .limit(limit);

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Sabit saatli yerleri getir (balon uçuşu gibi)
  async getFixedTimePlaces() {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .eq('is_time_fixed', true)
      .order('fixed_start_time', { ascending: true });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Balon uçuşu yerlerini getir
  async getBalloonFlights() {
    const { data, error } = await supabase
      .from('places')
      .select('*')
      .eq('type', 'hot_air_balloon')
      .eq('is_time_fixed', true);

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Smart Search (Web araması için Edge Function kullanır)
  async smartSearch(query: string, options: Record<string, unknown> = {}) {
    const { data, error } = await supabase.functions.invoke('smart-search', {
      body: { query, ...options }
    });
    if (error) throw error;
    return data;
  },

  // AI Search (Gemini destekli akıllı arama)
  async aiSearch(query: string, conversationHistory: Array<{ role: string; content: string }> = []) {
    const { data, error } = await supabase.functions.invoke('ai-search', {
      body: { query, conversationHistory }
    });
    if (error) throw error;
    return data;
  },

  // Image Generation (AI ile görsel oluşturma)
  async generateImage(contents: Array<{ text: string }>) {
    const { data, error } = await supabase.functions.invoke('generate-image', {
      body: { contents }
    });
    if (error) throw error;
    return data;
  },

  // Image Generation Task Status (Görsel oluşturma görev durumu sorgulama)
  async queryImageTask(taskId: string) {
    const { data, error } = await supabase.functions.invoke('query-image-task', {
      body: { taskId }
    });
    if (error) throw error;
    return data;
  },
};

/**
 * GÜVENLİ PLACES API
 */
export const placesApiSafe = {
  ...placesApi,

  // Şehre göre yerleri getir (GÜVENLİ)
  async getByCity(city: string) {
    return safeExecute(async () => {
      const sanitizedCity = validators.city(city, 'Şehir');
      const { data, error } = await supabase
        .from('places')
        .select('*')
        .ilike('city', `%${sanitizedCity}%`)
        .order('rating', { ascending: false });

      if (error) throw error;
      return Array.isArray(data) ? data : [];
    }, 'Şehir bilgisine göre yerler getirilirken bir hata oluştu.');
  },

  // Ülkeye göre yerleri getir (GÜVENLİ)
  async getByCountry(country: string) {
    return safeExecute(async () => {
      const sanitizedCountry = validators.country(country, 'Ülke');
      const { data, error } = await supabase
        .from('places')
        .select('*')
        .ilike('country', `%${sanitizedCountry}%`)
        .order('rating', { ascending: false });

      if (error) throw error;
      return Array.isArray(data) ? data : [];
    }, 'Ülke bilgisine göre yerler getirilirken bir hata oluştu.');
  },

  // Türe göre yerleri getir (GÜVENLİ)
  async getByType(type: string) {
    return safeExecute(async () => {
      const sanitizedType = validators.type(type, 'Tür');
      const { data, error } = await supabase
        .from('places')
        .select('*')
        .ilike('type', `%${sanitizedType}%`)
        .order('rating', { ascending: false });

      if (error) throw error;
      return Array.isArray(data) ? data : [];
    }, 'Tür bilgisine göre yerler getirilirken bir hata oluştu.');
  },

  // Arama yap (GÜVENLİ + RATE LIMIT)
  async search(query: string) {
    return safeExecute(async () => {
      checkRateLimit('places-search');
      const sanitizedQuery = validators.searchQuery(query, 'Arama terimi');

      const { data, error } = await supabase
        .from('places')
        .select('*')
        .or(`name.ilike.%${sanitizedQuery}%,city.ilike.%${sanitizedQuery}%,country.ilike.%${sanitizedQuery}%,description.ilike.%${sanitizedQuery}%`)
        .order('rating', { ascending: false })
        .limit(20);

      if (error) throw error;
      return Array.isArray(data) ? data : [];
    }, 'Arama yapılırken bir hata oluştu.');
  },

  // ID'ye göre yer getir (GÜVENLİ)
  async getById(id: string) {
    return safeExecute(async () => {
      const sanitizedId = validators.uuid(id, 'Yer ID');
      const { data, error } = await supabase
        .from('places')
        .select('*')
        .eq('id', sanitizedId)
        .maybeSingle();

      if (error) throw error;
      return data;
    }, 'Yer bilgisi getirilirken bir hata oluştu.');
  }
};

/**
 * MİGRASYON REHBERİ (Eski Kodu Yeni Koda Geçirme)
 * 
 * 1. İmport Değişikliği:
 *    Eski: import { placesApi } from '@/db/api';
 *    Yeni: import { placesApiSafe as placesApi } from '@/db/api';
 * 
 * 2. Try-Catch Blokları:
 *    Eski kodda manuel try-catch kullanıyorsanız, safeApi zaten hata fırlatır
 *    ve kullanıcı dostu mesajlar içerir. Yine de özel işlemler için try-catch kalabilir.
 * 
 * 3. Input Validation:
 *    Artık inputlar API katmanında doğrulanır. Boş veya çok kısa aramalar
 *    otomatik olarak reddedilir ve Türkçe hata mesajı döner.
 */


// Trips API
export const tripsApi = {
  // Kullanıcının seyahatlerini getir
  async getUserTrips(userId: string) {
    const { data, error } = await supabase
      .from('trips')
      .select('*')
      .eq('user_id', userId)
      .order('created_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Herkese açık seyahatleri getir
  async getPublicTrips(limit: number = 20) {
    const { data, error } = await supabase
      .from('trips')
      .select(`
        *,
        profiles:user_id (username, avatar_url)
      `)
      .eq('is_public', true)
      .order('created_at', { ascending: false })
      .limit(limit);

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Seyahat detayını getir
  async getTripById(tripId: string) {
    console.log('🔍 API: Fetching trip by ID:', tripId);
    
    // Auth check
    const { data: { user } } = await supabase.auth.getUser();

    // Eğer kullanıcı giriş yapmamışsa, token ile getirmeyi dene
    if (!user) {
      const token = localStorage.getItem(`trip_token_${tripId}`);
      if (token) {
        console.log('🔍 API: Using anonymous token for session headers');
        // ✨ Set headers for the current session to allow subsequent queries to succeed via RLS
        try {
          if ((supabase as any).rest) {
            (supabase as any).rest.headers['x-trip-token'] = token;
            (supabase as any).rest.headers['x-anonymous-token'] = token;
          }
        } catch (e) {
          console.warn('❌ API: Error setting anonymous headers:', e);
        }
      }
    }

    // Normal fetch (logged-in or public trip or anonymous trip with headers set above)
    const { data, error } = await supabase
      .from('trips')
      .select(`
        *,
        trip_days!trip_days_trip_id_fkey (
          *,
          trip_places (
            *,
            places (*)
          )
        )
      `)
      .eq('id', tripId)
      .order('day_number', { foreignTable: 'trip_days', ascending: true })
      .order('order_index', { foreignTable: 'trip_days.trip_places', ascending: true })
      .maybeSingle();

    if (error) {
      console.error('❌ API: Error fetching trip:', error);
      throw error;
    }
    
    return data;
  },

  // Yeni seyahat oluştur
  async create(trip: {
    title: string;
    description?: string;
    destination?: string;
    start_date?: string;
    end_date?: string;
    cover_image?: string;
    is_public?: boolean;
    interests?: string[];
    start_location_type?: 'hotel' | 'custom' | 'city_center';
    start_location_name?: string;
    start_lat?: number;
    start_lng?: number;
    number_of_travelers?: number;
  }) {
    const { data: { user } } = await supabase.auth.getUser();
    
    // Kullanıcı varsa user_id ekle, yoksa anonim token oluştur
    let tripData: typeof trip & { user_id: string | null; anonymous_token?: string };
    let anonymousToken: string | null = null;
    
    if (user) {
      tripData = { ...trip, user_id: user.id };
    } else {
      // Anonim kullanıcı için token oluştur
      anonymousToken = crypto.randomUUID();
      tripData = { ...trip, user_id: null, anonymous_token: anonymousToken };
    }

    const { data, error } = await supabase
      .from('trips')
      .insert([tripData])
      .select()
      .single();

    if (error) throw error;
    
    // Anonim token'ı localStorage'a kaydet
    if (anonymousToken && data) {
      localStorage.setItem(`trip_token_${data.id}`, anonymousToken);
    }
    
    return data;
  },

  // Seyahati güncelle
  async update(tripId: string, updates: TripUpdateData) {
    const { data: { user } } = await supabase.auth.getUser();
    
    // Eğer kullanıcı giriş yapmamışsa, token ile güncelleme yap
    if (!user) {
      const token = localStorage.getItem(`trip_token_${tripId}`);
      if (!token) {
        throw new Error('Bu geziyi güncellemek için yetkiniz yok');
      }
      
      // RPC fonksiyonu ile güncelle
      const { data, error } = await supabase.rpc('update_anonymous_trip', {
        trip_id_param: tripId,
        token_param: token,
        updates: updates as unknown as Record<string, unknown>
      });
      
      if (error) throw error;
      return data;
    }
    
    // Giriş yapmış kullanıcı için normal güncelleme
    const { data, error } = await supabase
      .from('trips')
      .update(updates)
      .eq('id', tripId)
      .select()
      .single();

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

  // Seyahat başlangıç noktasını güncelle
  async updateStartLocation(
    tripId: string, 
    startLocation: {
      type: 'balloon' | 'hotel' | 'place' | 'city_center';
      lat: number;
      lng: number;
    }
  ) {
    const { data, error } = await supabase
      .from('trips')
      .update({
        start_location_type: startLocation.type,
        start_lat: startLocation.lat,
        start_lng: startLocation.lng,
      })
      .eq('id', tripId)
      .select()
      .single();

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

  // Seyahati sil
  async delete(tripId: string) {
    const { data: { user } } = await supabase.auth.getUser();
    
    // Eğer kullanıcı giriş yapmamışsa, token ile silme yap
    if (!user) {
      const token = localStorage.getItem(`trip_token_${tripId}`);
      if (!token) {
        throw new Error('Bu geziyi silmek için yetkiniz yok');
      }
      
      // RPC fonksiyonu ile sil
      const { data, error } = await supabase.rpc('delete_anonymous_trip', {
        trip_id_param: tripId,
        token_param: token
      });
      
      if (error) throw error;
      if (!data) {
        throw new Error('Gezi bulunamadı veya token geçersiz');
      }
      
      // Token'ı temizle
      localStorage.removeItem(`trip_token_${tripId}`);
      return;
    }
    
    // Giriş yapmış kullanıcı için normal silme
    const { error } = await supabase
      .from('trips')
      .delete()
      .eq('id', tripId);

    if (error) throw error;
  },

  // Public slug ile seyahat getir (login gerektirmez)
  async getTripBySlug(slug: string) {
    const { data, error } = await supabase
      .from('trips')
      .select(`
        *,
        trip_days!trip_days_trip_id_fkey (
          *,
          trip_places (
            *,
            places (*)
          )
        )
      `)
      .eq('public_slug', slug)
      .eq('is_public', true)
      .order('day_number', { foreignTable: 'trip_days', ascending: true })
      .order('order_index', { foreignTable: 'trip_days.trip_places', ascending: true })
      .maybeSingle();

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

  // Seyahati public yap ve slug oluştur
  async makePublic(tripId: string, slug: string) {
    const { data, error } = await supabase
      .from('trips')
      .update({ 
        is_public: true, 
        public_slug: slug 
      })
      .eq('id', tripId)
      .select()
      .single();

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

  // Seyahati private yap
  async makePrivate(tripId: string) {
    const { data, error } = await supabase
      .from('trips')
      .update({ 
        is_public: false 
      })
      .eq('id', tripId)
      .select()
      .single();

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

  // Anonim geziyi kullanıcıya transfer et (login sonrası)
  async claimAnonymousTrip(tripId: string) {
    const token = localStorage.getItem(`trip_token_${tripId}`);
    if (!token) {
      console.warn('Token bulunamadı, gezi zaten kullanıcıya ait olabilir');
      return null;
    }

    const { data, error } = await supabase.rpc('claim_anonymous_trip', {
      trip_id_param: tripId,
      token_param: token
    });

    if (error) {
      console.error('Gezi transfer edilemedi:', error);
      throw error;
    }

    // Başarılı transfer sonrası token'ı temizle
    if (data) {
      localStorage.removeItem(`trip_token_${tripId}`);
    }

    return data;
  },

  // İlgi alanlarına göre otomatik plan oluştur
  async generateItinerary(
    tripId: string,
    interests: string[],
    startDate: string,
    endDate: string,
    destination: string,
    mode: 'auto_seed' | 'suggestion' = 'auto_seed'
  ) {
    console.log('generateItinerary çağrıldı:', { tripId, interests, startDate, endDate, destination, mode });
    
    if (mode === 'auto_seed') {
      return this.generateAutoSeedItinerary(tripId, interests, destination);
    } else {
      // Suggestion mode için gelecekte AI önerileri eklenebilir
      return this.generateAutoSeedItinerary(tripId, interests, destination);
    }
  },

  // AUTO_SEED MODE: Kurallar ile otomatik plan oluştur
  async generateAutoSeedItinerary(
    tripId: string,
    interests: string[],
    destination: string
  ) {
    console.log('AUTO_SEED MODE (FINAL):', { tripId, interests, destination });

    const {
      shouldAddBalloon,
      getPlacesByInterests,
      getTypicalDuration,
      MAX_PLACES_PER_DAY,
      MIN_PLACES_PER_DAY,
      BALLOON_PLACE_TYPE,
      isValidForDay,           // ← YENİ: Yer validasyonu
      getPlaceCategory,        // ← YENİ: Yer kategorisi
      PLACE_TYPE_CATEGORIES,   // ← YENİ: Kategori tanımları
    } = await import('@/config/cappadocia-rules');

    /* ------------------------------------------------------------------ */
    /* 1. TRIP + DAYS                                                      */
    /* ------------------------------------------------------------------ */
    const { data: trip } = await supabase
      .from('trips')
      .select('*')
      .eq('id', tripId)
      .single();

    if (!trip) throw new Error('Trip not found');

    const { data: days } = await supabase
      .from('trip_days')
      .select('*')
      .eq('trip_id', tripId)
      .order('day_number', { ascending: true });

    if (!days || days.length === 0) {
      throw new Error('Trip has no days');
    }

    /* ------------------------------------------------------------------ */
    /* 2. PLACES FETCH (AUTO-SEED: NO DESTINATION FILTER)                 */
    /* ------------------------------------------------------------------ */
    const { data: allPlaces, error: placesError } = await supabase
      .from('places')
      .select('*')
      .order('rating', { ascending: false })
      .limit(150);

    if (placesError) {
      console.error('❌ Places fetch error:', placesError);
      throw placesError;
    }

    if (!allPlaces || allPlaces.length === 0) {
      throw new Error('No places found in database');
    }

    const scoredPlaces = getPlacesByInterests(allPlaces, interests);

    /* ------------------------------------------------------------------ */
    /* 3. CONTEXT                                                         */
    /* ------------------------------------------------------------------ */
    const usedPlaceIds = new Set<string>();
    let balloonAdded = trip.has_balloon ?? false;

    const MAX_PER_DAY = Math.max(3, MAX_PLACES_PER_DAY || 4);
    const MIN_PER_DAY = Math.max(3, MIN_PLACES_PER_DAY || 3);

    /* ------------------------------------------------------------------ */
    /* 4. HELPERS                                                         */
    /* ------------------------------------------------------------------ */
    const isHotel = (p: any) => p.type === 'hotel';

    const isRestaurant = (p: any) =>
      p.type === 'restaurant' || p.type === 'cafe';

    const getCentroid = (places: any[]) => {
      const coords = places.filter(p => p.latitude && p.longitude);
      if (coords.length === 0) return null;

      const lat =
        coords.reduce((s, p) => s + p.latitude, 0) / coords.length;
      const lng =
        coords.reduce((s, p) => s + p.longitude, 0) / coords.length;

      return { lat, lng };
    };

    const distance = (a: any, b: any) => {
      const R = 6371000;
      const dLat = ((b.lat - a.lat) * Math.PI) / 180;
      const dLng = ((b.lng - a.lng) * Math.PI) / 180;
      const sa = Math.sin(dLat / 2);
      const sb = Math.sin(dLng / 2);
      return (
        2 *
        R *
        Math.asin(
          Math.sqrt(
            sa * sa +
              Math.cos((a.lat * Math.PI) / 180) *
                Math.cos((b.lat * Math.PI) / 180) *
                sb *
                sb
          )
        )
      );
    };

    /* ------------------------------------------------------------------ */
    /* 5. DAY LOOP                                                         */
    /* ------------------------------------------------------------------ */
    for (let dayIndex = 0; dayIndex < days.length; dayIndex++) {
      const day = days[dayIndex];
      const dayPlaces: any[] = [];

      /* ---- BALLOON --------------------------------------------------- */
      if (
        shouldAddBalloon(dayIndex, days.length, interests, balloonAdded)
      ) {
        const balloon = scoredPlaces.find(
          p => p.type === BALLOON_PLACE_TYPE
        );

        if (balloon) {
          await supabase
            .from('trips')
            .update({
              has_balloon: true,
              balloon_day_id: day.id,
            })
            .eq('id', tripId);

          dayPlaces.push(balloon);
          usedPlaceIds.add(balloon.id);
          balloonAdded = true;
        }
      }

      /* ---- FLEXIBLE PLACES (museum, park, viewpoint...) -------------- */
      for (const place of scoredPlaces) {
        if (dayPlaces.length >= MAX_PER_DAY) break;
        if (usedPlaceIds.has(place.id)) continue;
        if (isHotel(place)) continue;
        
        // ✨ KURAL KONTROLÜ: Type-based validation (LIMITED, EXCLUDED, FLEXIBLE)
        if (!isValidForDay(place, dayPlaces, usedPlaceIds, { balloonAdded })) {
          continue;
        }

        dayPlaces.push(place);
        usedPlaceIds.add(place.id);
      }

      /* ---- SMART RESTAURANT (1 per day, near centroid) ---------------- */
      const hasRestaurant = dayPlaces.some(isRestaurant);
      if (!hasRestaurant && dayPlaces.length > 0) {
        const center = getCentroid(dayPlaces);

        if (center) {
          const restaurants = scoredPlaces
            .filter(
              p =>
                isRestaurant(p) &&
                !usedPlaceIds.has(p.id) &&
                p.latitude &&
                p.longitude
            )
            .map(r => ({
              ...r,
              d: distance(center, {
                lat: r.latitude,
                lng: r.longitude,
              }),
            }))
            .filter(r => r.d < 1500)
            .sort((a, b) => a.d - b.d);

          if (restaurants.length > 0) {
            const restaurant = restaurants[0];
            
            // ✨ KURAL KONTROLÜ: Type-based validation (LIMITED rule)
            if (isValidForDay(restaurant, dayPlaces, usedPlaceIds, { balloonAdded })) {
              dayPlaces.splice(1, 0, restaurant);
              usedPlaceIds.add(restaurant.id);
            }
          }
        }
      }

      /* ---- MIN FILL -------------------------------------------------- */
      if (dayPlaces.length < MIN_PER_DAY) {
        for (const p of scoredPlaces) {
          if (dayPlaces.length >= MIN_PER_DAY) break;
          if (usedPlaceIds.has(p.id)) continue;
          if (isHotel(p)) continue;

          // ✨ KURAL KONTROLÜ: Type-based validation (LIMITED, EXCLUDED, FLEXIBLE)
          if (!isValidForDay(p, dayPlaces, usedPlaceIds, { balloonAdded })) {
            continue;
          }

          dayPlaces.push(p);
          usedPlaceIds.add(p.id);
        }
      }

      /* ---------------------------------------------------------------- */
      /* 6. INSERT trip_places                                             */
      /* ---------------------------------------------------------------- */
      for (let i = 0; i < dayPlaces.length; i++) {
        const place = dayPlaces[i];

        let durationMinutes = 120;
        const typical = getTypicalDuration(place.type || 'default');
        const match = typical?.match?.(/(\d+)/);
        if (match) durationMinutes = parseInt(match[1], 10) * 60;

        await supabase.from('trip_places').insert({
          trip_day_id: day.id,
          place_id: place.id,
          order_index: i,
          duration: `${durationMinutes} dakika`,
        });
      }
    }

    // ✅ NEW: Tour Assignment
    console.log('🎯 Tour assignment başlıyor...');

    try {
      // Full trip data al
      const { data: fullTrip } = await supabase
        .from('trips')
        .select(`
          *,
          days:trip_days(
            *,
            places:trip_places(
              *,
              place:places(*)
            )
          )
        `)
        .eq('id', tripId)
        .single();

      if (fullTrip && fullTrip.days && fullTrip.days.length > 0) {
        const { analyzeTripPlan, matchDailyTourRuleBased } = await import(
          '@/lib/tour-matching'
        );

        // Analyze trip
        const analysis = analyzeTripPlan(fullTrip);
        console.log('Trip analysis:', analysis);

        // Match best tour
        const tourMatch = matchDailyTourRuleBased(analysis);
        console.log('Tour match:', tourMatch);

        if (tourMatch) {
          // Update all days with suggested tour
          for (const day of fullTrip.days) {
            await supabase
              .from('trip_days')
              .update({ suggested_tour_slug: tourMatch.daily_tour_slug })
              .eq('id', day.id);

            console.log(`Day ${day.day_number}: ${tourMatch.daily_tour_slug}`);
          }

          console.log('✅ Tour assignment completed');
        }
      }
    } catch (tourError: any) {
      console.error('Tour assignment error (non-critical):', tourError);
      // Continue even if tour assignment fails
    }

    console.log('AUTO_SEED COMPLETE ✅');
  },

  // Eski anonim gezileri temizle (admin veya cron job için)
  async cleanupOldAnonymousTrips() {
    const { data, error } = await supabase.rpc('cleanup_old_anonymous_trips');
    
    if (error) {
      console.error('Anonim geziler temizlenirken hata:', error);
      throw error;
    }
    
    console.log(`✅ ${data} adet eski anonim gezi temizlendi`);
    return data;
  },

  // Bir gezinin erişilebilir olup olmadığını kontrol et
  async canAccessTrip(tripId: string): Promise<boolean> {
    const { data: { user } } = await supabase.auth.getUser();
    
    // Kullanıcı giriş yapmışsa, kendi gezisini kontrol et
    if (user) {
      const { data } = await supabase
        .from('trips')
        .select('id')
        .eq('id', tripId)
        .eq('user_id', user.id)
        .maybeSingle();
      
      return !!data;
    }
    
    // Anonim kullanıcı için token kontrolü
    const token = localStorage.getItem(`trip_token_${tripId}`);
    if (!token) return false;
    
    const { data } = await supabase.rpc('get_anonymous_trip', {
      trip_id_param: tripId,
      token_param: token
    });
    
    return !!data && Array.isArray(data) && data.length > 0;
  },
};

// Trip Days API

/**
 * GÜVENLİ TRIPS API
 */
export const tripsApiSafe = {
  ...tripsApi,

  // Seyahat detayını getir (GÜVENLİ)
  async getTripById(tripId: string) {
    return safeExecute(async () => {
      const sanitizedId = validators.uuid(tripId, 'Seyahat ID') as string;
      return await tripsApi.getTripById(sanitizedId);
    }, 'Seyahat detayları getirilirken bir hata oluştu.');
  },

  // Kullanıcının seyahatlerini getir (GÜVENLİ)
  async getUserTrips(userId: string) {
    return safeExecute(async () => {
      const sanitizedId = validators.uuid(userId, 'Kullanıcı ID') as string;
      return await tripsApi.getUserTrips(sanitizedId);
    }, 'Seyahatleriniz getirilirken bir hata oluştu.');
  },

  // Yeni seyahat oluştur (GÜVENLİ + AUTH OPTIONAL + RATE LIMITED)
  async create(trip: {
    title: string;
    description?: string;
    destination?: string;
    start_date?: string;
    end_date?: string;
    cover_image?: string;
    is_public?: boolean;
    interests?: string[];
    start_location_type?: 'hotel' | 'custom' | 'city_center';
    start_location_name?: string;
    start_lat?: number;
    start_lng?: number;
    number_of_travelers?: number;
    user_id?: string | null;
  }) {
    return safeExecute(async () => {
      // 1. AUTH CHECK - OPTIONAL (allow anonymous trips)
      // Since we use Clerk, we pass user_id (profile UUID) from the frontend
      const passedUserId = trip.user_id;
      
      // User exists -> add user_id, else set to null and generate anonymous_token
      let anonymousToken: string | null = null;
      let tripData: any;
      
      if (passedUserId) {
        tripData = { ...trip };
      } else {
        // Anonim kullanıcı için token oluştur
        anonymousToken = crypto.randomUUID();
        tripData = { ...trip, user_id: null, anonymous_token: anonymousToken };
      }

      // 2. RATE LIMITING - Only for authenticated users
      if (passedUserId) {
        const rateLimitKey = `trip_create_${passedUserId}`;
        try {
          checkHourlyRateLimit(rateLimitKey, 5);
        } catch (error: any) {
          logSecurityEvent('TRIP_CREATE_RATE_LIMITED', passedUserId, { 
            reason: 'Rate limit exceeded',
            message: error.message 
          });
          throw error;
        }
      }

      // 3. INPUT VALIDATION
      try {
        validateTripData(trip);
      } catch (error: any) {
        logSecurityEvent('TRIP_CREATE_VALIDATION_FAILED', passedUserId || null, { 
          reason: 'Invalid input',
          error: error.message,
          tripData: { title: trip.title, destination: trip.destination }
        });
        throw error;
      }

      // 4. CREATE TRIP
      const { data, error } = await supabase
        .from('trips')
        .insert([tripData])
        .select()
        .single();

      if (error) {
        logSecurityEvent('TRIP_CREATE_DB_ERROR', passedUserId || null, { 
          reason: 'Database error',
          error: error.message,
          code: error.code 
        });
        throw new Error('Seyahat oluşturulurken bir hata oluştu. Lütfen tekrar deneyin.');
      }

      // 5. SUCCESS LOG
      logSecurityEvent('TRIP_CREATE_SUCCESS', passedUserId || null, { 
        tripId: data.id,
        title: data.title,
        destination: data.destination 
      });

      // 6. STORE ANONYMOUS TOKEN
      if (anonymousToken && data) {
        localStorage.setItem(`trip_token_${data.id}`, anonymousToken);
        localStorage.setItem('currentTripId', data.id); // Transfer için tripId'yi sakla
        
        // ✨ Set headers for the current session to allow subsequent queries (createDays, itinerary)
        try {
          if ((supabase as any).rest) {
            (supabase as any).rest.headers['x-trip-token'] = anonymousToken;
            (supabase as any).rest.headers['x-anonymous-token'] = anonymousToken;
          }
        } catch (e) {
          console.warn('❌ API: Error setting anonymous headers for current session:', e);
        }
      }

      return data;
    }, 'Seyahat oluşturulurken bir hata oluştu.');
  }
};

export const tripDaysApi = {
  // Seyahate göre günleri getir
  async getByTripId(tripId: string) {
    const { data, error } = await supabase
      .from('trip_days')
      .select('*')
      .eq('trip_id', tripId)
      .order('day_number', { ascending: true });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Tarih aralığına göre günleri oluştur
  async createDaysForTrip(tripId: string, startDate: string, endDate: string) {
    const start = new Date(startDate);
    const end = new Date(endDate);
    const days = Math.ceil((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)) + 1;
    
    console.log(`${days} gün oluşturuluyor...`);
    
    const createdDays: any[] = [];
    for (let dayNum = 1; dayNum <= days; dayNum++) {
      const currentDate = new Date(start);
      currentDate.setDate(start.getDate() + dayNum - 1);
      
      const { data: day, error: dayError } = await supabase
        .from('trip_days')
        .insert([{
          trip_id: tripId,
          day_number: dayNum,
          date: currentDate.toISOString().split('T')[0],
        }])
        .select()
        .single();
      
      if (dayError) {
        console.error(`Gün ${dayNum} oluşturma hatası:`, dayError);
        throw dayError;
      }
      
      console.log(`Gün ${dayNum} oluşturuldu:`, day.id);
      createdDays.push(day);
    }
    
    return createdDays;
  },

  // Seyahate gün ekle
  async create(tripDay: {
    trip_id: string;
    day_number: number;
    date?: string;
    notes?: string;
  }) {
    const { data, error } = await (supabase as any)
      .from('trip_days')
      .insert([tripDay])
      .select()
      .single();

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

  // Günü güncelle
  async update(dayId: string, updates: any) {
    const { data, error } = await (supabase as any)
      .from('trip_days')
      .update(updates)
      .eq('id', dayId)
      .select()
      .single();

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

  // Günü sil
  async delete(dayId: string) {
    const { error } = await supabase
      .from('trip_days')
      .delete()
      .eq('id', dayId);

    if (error) throw error;
  },
};

// Trip Places API
export const tripPlacesApi = {
  // Güne yer ekle
  async addToDay(tripPlace: {
    trip_day_id: string;
    place_id: string;
    order_index?: number;
    duration?: string;
    notes?: string;
    time_block?: string;
  }) {
    const { data, error } = await (supabase as any)
      .from('trip_places')
      .insert([tripPlace])
      .select()
      .single();

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

  // Güne göre yerleri getir
  async getByDayId(dayId: string) {
    const { data, error } = await supabase
      .from('trip_places')
      .select('*')
      .eq('trip_day_id', dayId)
      .order('order_index', { ascending: true });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Güne ve yere göre kontrol et
  async getByDayAndPlace(dayId: string, placeId: string) {
    const { data, error } = await supabase
      .from('trip_places')
      .select('*')
      .eq('trip_day_id', dayId)
      .eq('place_id', placeId)
      .maybeSingle();

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

  // Yer notunu güncelle
  async update(tripPlaceId: string, updates: any) {
    const { data, error } = await (supabase as any)
      .from('trip_places')
      .update(updates)
      .eq('id', tripPlaceId)
      .select()
      .single();

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

  // Yeri günden çıkar
  async remove(tripPlaceId: string) {
    const { error } = await supabase
      .from('trip_places')
      .delete()
      .eq('id', tripPlaceId);

    if (error) throw error;
  },

  // Tek bir place'in order_index'ini güncelle
  async updateOrderIndex(tripPlaceId: string, orderIndex: number) {
    const { error } = await supabase
      .from('trip_places')
      .update({ order_index: orderIndex })
      .eq('id', tripPlaceId);

    if (error) throw error;
  },

  // Toplu order_index güncelleme (drag & drop için)
  async updatePlacesOrder(tripDayId: string, places: Array<{ tripPlaceId: string; orderIndex: number }>) {
    // Her place için update işlemi yap
    const updatePromises = places.map(({ tripPlaceId, orderIndex }) =>
      supabase
        .from('trip_places')
        .update({ order_index: orderIndex })
        .eq('id', tripPlaceId)
        .eq('trip_day_id', tripDayId)
    );

    const results = await Promise.all(updatePromises);
    
    // Hata kontrolü
    const errors = results.filter(r => r.error);
    if (errors.length > 0) {
      console.error('Order güncelleme hataları:', errors);
      throw new Error('Sıralama güncellenirken hata oluştu');
    }

    return true;
  },

  // Rota optimizasyonu için girdileri hazırla
  async getRouteOptimizationInput(dayId: string, dayPlaces: any[], trip?: any) {
    // Koordinatları olan yerleri filtrele
    const placesWithCoords = dayPlaces.filter(
      (p: any) => p.position?.lat && p.position?.lng
    );

    if (placesWithCoords.length < 2) {
      throw new Error('En az 2 yer gerekli ve koordinatları olmalı');
    }

    // Optimizasyon için gerekli veriyi hazırla
    const places = placesWithCoords.map((p: any) => ({
      tripPlaceId: p.tripPlaceId,
      placeId: p.id,
      name: p.name,
      lat: p.position.lat,
      lng: p.position.lng,
      duration: p.duration || '1 saat',
      order_index: p.order_index,
      is_time_fixed: p.is_time_fixed || false,
      fixed_start_time: p.fixed_start_time,
      fixed_end_time: p.fixed_end_time,
    }));

    // Başlangıç noktasını belirle (öncelik: balon > otel > ilk yer)
    let startLocation: { lat: number; lng: number } | null = null;
    let startLocationType = 'place';

    // 1. Balon uçuşu varsa
    const balloonPlace = places.find((p: any) => p.is_time_fixed && p.name?.toLowerCase().includes('balon'));
    if (balloonPlace) {
      startLocation = { lat: balloonPlace.lat, lng: balloonPlace.lng };
      startLocationType = 'balloon';
    }
    // 2. Otel konumu varsa
    else if (trip?.start_location_type === 'hotel' && trip?.start_lat && trip?.start_lng) {
      startLocation = { lat: trip.start_lat, lng: trip.start_lng };
      startLocationType = 'hotel';
    }
    // 3. İlk yer
    else {
      startLocation = { lat: places[0].lat, lng: places[0].lng };
      startLocationType = 'place';
    }

    return {
      dayId,
      places,
      startLocation,
      startLocationType,
      travelMode: 'car',
      maxDayTime: '09:00-21:00',
    };
  },

  // Rota optimizasyonu Edge Function'ını çağır
  async optimizeRoute(optimizationInput: any) {
    const { data, error } = await supabase.functions.invoke('optimize-route', {
      body: optimizationInput,
    });

    if (error) {
      console.error('Route optimization error:', error);
      throw error;
    }

    return data;
  },

  // Optimize edilmiş sıralamayı uygula
  async applyOptimizedOrder(
    tripDayId: string,
    optimizedOrder: Array<{ tripPlaceId: string; newOrderIndex: number }>
  ) {
    const places = optimizedOrder.map((item) => ({
      tripPlaceId: item.tripPlaceId,
      orderIndex: item.newOrderIndex,
    }));

    return await this.updatePlacesOrder(tripDayId, places);
  },
};

// Collections API
export const collectionsApi = {
  // Kullanıcının koleksiyonlarını getir
  async getUserCollections() {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

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

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Yeni koleksiyon oluştur
  async create(collection: { name: string; description?: string; icon?: string }) {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    const { data, error } = await (supabase as any)
      .from('collections')
      .insert([{ ...collection, user_id: user.id }])
      .select()
      .single();

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

  // Koleksiyonu güncelle
  async update(collectionId: string, updates: any) {
    const { data, error } = await (supabase as any)
      .from('collections')
      .update(updates)
      .eq('id', collectionId)
      .select()
      .single();

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

  // Koleksiyonu sil
  async delete(collectionId: string) {
    const { error } = await supabase
      .from('collections')
      .delete()
      .eq('id', collectionId);

    if (error) throw error;
  },
};

// Bookmarks API
export const bookmarksApi = {
  // Kullanıcının tüm kayıtlarını getir
  async getUserBookmarks(collectionId?: string) {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    let query = supabase
      .from('bookmarks')
      .select(`
        *,
        places (*)
      `)
      .eq('user_id', user.id)
      .order('created_at', { ascending: false });

    if (collectionId) {
      query = query.eq('collection_id', collectionId);
    }

    const { data, error } = await query;

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Favori yerleri getir
  async getFavorites() {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    const { data, error } = await supabase
      .from('bookmarks')
      .select(`
        *,
        places (*)
      `)
      .eq('user_id', user.id)
      .eq('is_favorite', true)
      .order('created_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Yer kaydedilmiş mi kontrol et
  async isBookmarked(placeId: string) {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) return false;

    const { data, error } = await supabase
      .from('bookmarks')
      .select('id')
      .eq('user_id', user.id)
      .eq('place_id', placeId)
      .maybeSingle();

    if (error) return false;
    return !!data;
  },

  // Yer kaydet
  async bookmark(placeId: string, collectionId?: string, isFavorite: boolean = false) {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    const { data, error } = await (supabase as any)
      .from('bookmarks')
      .insert([{
        user_id: user.id,
        place_id: placeId,
        collection_id: collectionId,
        is_favorite: isFavorite,
      }])
      .select()
      .single();

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

  // Kaydı kaldır
  async unbookmark(placeId: string) {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    const { error } = await supabase
      .from('bookmarks')
      .delete()
      .eq('user_id', user.id)
      .eq('place_id', placeId);

    if (error) throw error;
  },

  // Favoriye ekle/çıkar
  async toggleFavorite(placeId: string) {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    // Önce bookmark var mı kontrol et
    const { data: existing } = await supabase
      .from('bookmarks')
      .select('id, is_favorite')
      .eq('user_id', user.id)
      .eq('place_id', placeId)
      .maybeSingle();

    if (existing) {
      // Varsa favoriye ekle/çıkar
      const { error } = await (supabase as any)
        .from('bookmarks')
        .update({ is_favorite: !existing.is_favorite })
        .eq('id', existing.id);

      if (error) throw error;
    } else {
      // Yoksa favoriye ekleyerek kaydet
      await this.bookmark(placeId, undefined, true);
    }
  },

  // Koleksiyonu değiştir
  async moveToCollection(bookmarkId: string, collectionId: string) {
    const { error } = await (supabase as any)
      .from('bookmarks')
      .update({ collection_id: collectionId })
      .eq('id', bookmarkId);

    if (error) throw error;
  },
};

// Businesses API
export const businessesApi = {
  // İşletme oluştur
  async create(business: {
    name: string;
    description?: string;
    category?: string;
    phone?: string;
    email?: string;
    website?: string;
    logo_url?: string;
  }) {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    const { data, error } = await (supabase as any)
      .from('businesses')
      .insert([{ ...business, user_id: user.id }])
      .select()
      .single();

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

  // Kullanıcının işletmesini getir
  async getUserBusiness() {
    const { data: { user } } = await supabase.auth.getUser();
    if (!user) throw new Error('Kullanıcı girişi gerekli');

    const { data, error } = await supabase
      .from('businesses')
      .select('*')
      .eq('user_id', user.id)
      .maybeSingle();

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

  // İşletmeyi güncelle
  async update(businessId: string, updates: any) {
    const { data, error } = await (supabase as any)
      .from('businesses')
      .update(updates)
      .eq('id', businessId)
      .select()
      .single();

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

  // İşletme istatistiklerini getir
  async getStats(businessId: string) {
    const { data, error } = await supabase
      .from('business_stats')
      .select('*')
      .eq('business_id', businessId)
      .maybeSingle();

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

  // İşletmenin yerlerini getir
  async getPlaces(businessId: string) {
    const { data, error } = await supabase
      .from('business_places')
      .select(`
        *,
        places (*)
      `)
      .eq('business_id', businessId)
      .order('claimed_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Yer talep et
  async claimPlace(businessId: string, placeId: string) {
    const { data, error } = await (supabase as any)
      .from('business_places')
      .insert([{
        business_id: businessId,
        place_id: placeId,
        status: 'pending',
      }])
      .select()
      .single();

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

  // Yeni yer ekle (işletme tarafından)
  async addPlace(businessId: string, place: {
    name: string;
    description?: string;
    type?: string;
    city?: string;
    country?: string;
    image_url?: string;
    latitude?: number;
    longitude?: number;
  }) {
    const { data, error } = await (supabase as any)
      .from('places')
      .insert([{ ...place, business_id: businessId }])
      .select()
      .single();

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

// Site Settings API
export const siteSettingsApi = {
  // Tüm ayarları getir
  async getAll() {
    const { data, error } = await supabase
      .from('site_settings')
      .select('*');

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Belirli bir ayarı getir
  async getByKey(key: string) {
    const { data, error } = await supabase
      .from('site_settings')
      .select('*')
      .eq('key', key)
      .maybeSingle();

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

  // Ayarı güncelle veya oluştur
  async update(key: string, value: string) {
    // Önce ayarın var olup olmadığını kontrol et
    const { data: existing } = await supabase
      .from('site_settings')
      .select('id')
      .eq('key', key)
      .maybeSingle();

    if (existing) {
      // Güncelle
      const { data, error } = await supabase
        .from('site_settings')
        .update({ value, updated_at: new Date().toISOString() })
        .eq('key', key)
        .select()
        .maybeSingle();

      if (error) throw error;
      
      // Eğer site_name güncelleniyorsa, seo_settings'i de güncelle
      if (key === 'site_name') {
        try {
          await supabase.from('seo_settings').update({ site_name: value }).eq('id', (await supabase.from('seo_settings').select('id').maybeSingle()).data?.id);
        } catch (e) {
          console.error('SEO settings sync error:', e);
        }
      }
      
      return data;
    } else {
      // Yeni oluştur
      const { data, error } = await supabase
        .from('site_settings')
        .insert({ key, value })
        .select()
        .maybeSingle();

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

  // Resim yükle
  async uploadImage(file: File, path: string) {
    const fileExt = file.name.split('.').pop();
    const fileName = `${path}-${Date.now()}.${fileExt}`;
    const filePath = `${fileName}`;

    const { data, error } = await supabase.storage
      .from('site-assets')
      .upload(filePath, file, {
        cacheControl: '3600',
        upsert: true
      });

    if (error) throw error;

    // Public URL'i al
    const { data: { publicUrl } } = supabase.storage
      .from('site-assets')
      .getPublicUrl(filePath);

    return publicUrl;
  },

  // Eski resmi sil
  async deleteImage(url: string) {
    // URL'den dosya yolunu çıkar
    const urlParts = url.split('/');
    const filePath = urlParts[urlParts.length - 1];

    const { error } = await supabase.storage
      .from('site-assets')
      .remove([filePath]);

    if (error) throw error;
  },
};

// Leads API - Nitelikli seyahat lead'leri
export const leadsApi = {
  // Yeni lead oluştur (sadece onay verilmişse)
  async create(leadData: {
    trip_id: string;
    destination: string;
    start_date: string;
    end_date: string;
    number_of_travelers: number;
    interests: string[];
    planned_activities: any;
    timeline_snapshot: any;
    email: string;
    whatsapp: string;
    country: string;
    consent_given: boolean;
    trigger_source: 'save_modal' | 'planner_cta' | 'contextual_banner' | 'ai_route_recommendation';
    tour_selected_id?: string | null;
    tourist_persona?: any;
    persona_confidence?: number;
  }) {
    // Onay verilmemişse lead oluşturma
    if (!leadData.consent_given) {
      throw new Error('Lead oluşturmak için kullanıcı onayı gereklidir');
    }

    // Mevcut kullanıcıyı al (varsa)
    const { data: { user } } = await supabase.auth.getUser();

    const { data, error } = await supabase
      .from('leads')
      .insert([{
        ...leadData,
        user_id: user?.id || null,
      }])
      .select()
      .single();

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

  // Trip'e ait lead'leri getir
  async getByTripId(tripId: string) {
    const { data, error } = await supabase
      .from('leads')
      .select('*')
      .eq('trip_id', tripId)
      .order('created_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Lead durumunu güncelle (sadece admin)
  async updateStatus(leadId: string, status: 'new' | 'contacted' | 'converted' | 'closed') {
    const { data, error } = await supabase
      .from('leads')
      .update({ status })
      .eq('id', leadId)
      .select()
      .single();

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

  // Tüm lead'leri getir (sadece admin)
  async getAll(limit: number = 50) {
    const { data, error } = await supabase
      .from('leads')
      .select(`
        *,
        trips (
          title,
          destination
        )
      `)
      .order('created_at', { ascending: false })
      .limit(limit);

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },
};

/**
 * GÜVENLİ LEADS API
 */
export const leadsApiSafe = {
  ...leadsApi,

  // Trip'e ait lead'leri getir (GÜVENLİ)
  async getByTripId(tripId: string) {
    return safeExecute(async () => {
      const sanitizedId = validators.uuid(tripId, 'Trip ID') as string;
      return await leadsApi.getByTripId(sanitizedId);
    }, 'Lead bilgileri getirilirken bir hata oluştu.');
  }
};


// Provider Services API
export const providerServicesApi = {
  // Get provider's service configuration
  async get(providerId: string) {
    const { data, error } = await supabase
      .from('provider_services')
      .select('*')
      .eq('provider_id', providerId)
      .maybeSingle();

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

  // Get all provider services
  async getAll() {
    const { data, error } = await supabase
      .from('provider_services')
      .select('*')
      .order('created_at', { ascending: false});

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Get provider services by provider ID
  async getByProviderId(providerId: string) {
    const { data, error } = await supabase
      .from('provider_services')
      .select('*')
      .eq('provider_id', providerId)
      .maybeSingle();

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

  // Create or update provider services
  async upsert(serviceData: {
    provider_id: string;
    destinations: string[];
    activity_categories: string[];
    business_name?: string;
    business_description?: string;
    business_logo?: string;
    daily_tour_services?: string[];
    vehicle_types?: string[];
    languages?: string[];
  }) {
    // RLS sorunlarını aşmak için RPC kullanıyoruz (Clerk uyumluluğu için)
    const { data, error } = await supabase.rpc('upsert_provider_service', {
      p_service_data: serviceData
    });

    if (error) {
      console.error('Error in upsert_provider_service:', error);
      throw error;
    }
    return data;
  },
};

// Provider Wallet API
export const providerWalletApi = {
  // Get wallet balance
  async getBalance(providerId: string) {
    const { data, error } = await supabase
      .from('provider_wallets')
      .select('*')
      .eq('provider_id', providerId)
      .maybeSingle();

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

  // Get or create wallet
  async getOrCreate(providerId: string) {
    // Try to get existing wallet
    let { data, error } = await supabase
      .from('provider_wallets')
      .select('*')
      .eq('provider_id', providerId)
      .maybeSingle();

    // If doesn't exist, create it
    if (!data && !error) {
      const { data: newWallet, error: createError } = await supabase
        .from('provider_wallets')
        .insert({ provider_id: providerId, credit_balance: 0 })
        .select()
        .single();

      if (createError) throw createError;
      return newWallet;
    }

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

  // Add credits (admin only or payment integration)
  async addCredits(providerId: string, amount: number, description: string = 'Credit purchase') {
    const { data, error } = await supabase.rpc('add_credits', {
      p_provider_id: providerId,
      p_amount: amount,
      p_description: description,
    });

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

  // Get transaction history
  async getTransactions(providerId: string, limit: number = 50) {
    const { data, error } = await supabase
      .from('credit_transactions')
      .select('*')
      .eq('provider_id', providerId)
      .order('created_at', { ascending: false })
      .limit(limit);

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },
};

// Lead Purchases API
export const leadPurchasesApi = {
  // Purchase a lead (price is determined server-side from leads.final_price)
  async purchase(providerId: string, leadId: string) {
    const { data, error } = await supabase.rpc('purchase_lead', {
      p_provider_id: providerId,
      p_lead_id: leadId,
    });

    if (error) throw error;
    
    // Check if purchase was successful
    if (data && !data.success) {
      throw new Error(data.error || 'Purchase failed');
    }
    
    return data;
  },

  // Get purchased leads for provider
  async getPurchased(providerId: string) {
    const { data, error } = await supabase
      .from('lead_purchases')
      .select(`
        *,
        leads (
          *,
          trips (
            title,
            destination
          )
        )
      `)
      .eq('provider_id', providerId)
      .order('purchased_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Check if provider has purchased a specific lead
  async hasPurchased(providerId: string, leadId: string) {
    const { data, error } = await supabase
      .from('lead_purchases')
      .select('id')
      .eq('provider_id', providerId)
      .eq('lead_id', leadId)
      .maybeSingle();

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

// Provider Leads API (marketplace)
export const providerLeadsApi = {
  // Get available leads for provider (filtered by their service areas and categories)
  async getAvailable(providerId: string, filters?: {
    destinations?: string[];
    start_date_from?: string;
    start_date_to?: string;
    min_travelers?: number;
    max_travelers?: number;
    activity_categories?: string[];
  }) {
    console.log('[providerLeadsApi] getAvailable called for provider:', providerId);
    
    // First get provider's service configuration
    const providerService = await providerServicesApi.get(providerId);
    console.log('[providerLeadsApi] Provider service:', providerService);
    
    if (!providerService) {
      console.log('[providerLeadsApi] No provider service found, returning empty array');
      return [];
    }

    // Build query - use leads_for_providers view (already filters by consent_given = true)
    let query = supabase
      .from('leads_for_providers')
      .select('*')
      .eq('status', 'new');

    // Apply additional filters
    if (filters?.start_date_from) {
      query = query.gte('start_date', filters.start_date_from);
    }
    if (filters?.start_date_to) {
      query = query.lte('start_date', filters.start_date_to);
    }
    if (filters?.min_travelers) {
      query = query.gte('number_of_travelers', filters.min_travelers);
    }
    if (filters?.max_travelers) {
      query = query.lte('number_of_travelers', filters.max_travelers);
    }

    query = query.order('created_at', { ascending: false });

    const { data: leads, error } = await query;
    console.log('[providerLeadsApi] Query result - leads count:', leads?.length, 'error:', error);

    if (error) {
      console.error('[providerLeadsApi] Error fetching leads:', error);
      throw error;
    }
    if (!leads) return [];

    // Filter by provider's destinations (Flexible matching)
    let filteredLeads = leads;
    if (providerService.destinations && providerService.destinations.length > 0) {
      console.log('[providerLeadsApi] Filtering by destinations (flexible):', providerService.destinations);
      const providerDests = providerService.destinations.map((d: string) => d.toLowerCase().trim());
      
      filteredLeads = leads.filter(lead => {
        if (!lead.destination) return false;
        const leadDest = lead.destination.toLowerCase();
        // Check if lead destination contains any provider destination OR vice versa
        return providerDests.some((dest: string) => 
          leadDest.includes(dest) || dest.includes(leadDest)
        );
      });
      console.log('[providerLeadsApi] After destination filtering, leads count:', filteredLeads.length);
    }

    // Filter by activity categories (interests array overlap) - case insensitive
    if (providerService.activity_categories && providerService.activity_categories.length > 0) {
      // Normalize provider categories to lowercase for comparison
      const normalizedCategories = providerService.activity_categories.map((cat: string) => 
        cat.toLowerCase().trim()
      );
      console.log('[providerLeadsApi] Normalized provider categories:', normalizedCategories);
      
      filteredLeads = leads.filter(lead => {
        if (!lead.interests || lead.interests.length === 0) {
          console.log('[providerLeadsApi] Lead', lead.id, 'has no interests, filtering out');
          return false;
        }
        // Normalize lead interests
        const normalizedInterests = lead.interests.map((interest: string) => 
          interest.toLowerCase().trim()
        );
        // Check if any lead interest matches any provider category (case insensitive)
        const hasMatch = normalizedInterests.some((interest: string) => 
          normalizedCategories.includes(interest)
        );
        console.log('[providerLeadsApi] Lead', lead.id, 'interests:', normalizedInterests, 'match:', hasMatch);
        return hasMatch;
      });
      console.log('[providerLeadsApi] After category filtering, leads count:', filteredLeads.length);
    }

    // Check which leads are already purchased
    const { data: purchases } = await supabase
      .from('lead_purchases')
      .select('lead_id')
      .eq('provider_id', providerId);

    const purchasedLeadIds = new Set(purchases?.map(p => p.lead_id) || []);
    console.log('[providerLeadsApi] Purchased lead IDs:', Array.from(purchasedLeadIds));

    // Add preview/purchase status and blur contact info
    const result = filteredLeads.map(lead => ({
      ...lead,
      is_purchased: purchasedLeadIds.has(lead.id),
      email_preview: lead.email ? blurEmail(lead.email) : '',
      whatsapp_preview: lead.whatsapp ? blurPhone(lead.whatsapp) : '',
      // Remove full contact info from preview
      email: purchasedLeadIds.has(lead.id) ? lead.email : undefined,
      whatsapp: purchasedLeadIds.has(lead.id) ? lead.whatsapp : undefined,
      country: purchasedLeadIds.has(lead.id) ? lead.country : undefined,
    }));
    
    console.log('[providerLeadsApi] Returning', result.length, 'leads');
    return result;
  },

  // Get full lead details (only if purchased)
  async getFullDetails(providerId: string, leadId: string) {
    // Check if purchased
    const hasPurchased = await leadPurchasesApi.hasPurchased(providerId, leadId);
    
    if (!hasPurchased) {
      throw new Error('Lead not purchased. Purchase the lead to view full details.');
    }

    // Get full lead details
    const { data, error } = await supabase
      .from('leads')
      .select('*')
      .eq('id', leadId)
      .single();

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

  // Get purchased leads for provider
  async getPurchased(providerId: string) {
    try {
      console.log('[providerLeadsApi.getPurchased] Starting query for provider:', providerId);
      
      // Get all purchased lead IDs for this provider
      const { data: purchases, error: purchasesError } = await supabase
        .from('lead_purchases')
        .select('lead_id, purchased_at, credits_spent')
        .eq('provider_id', providerId)
        .order('purchased_at', { ascending: false });

      console.log('[providerLeadsApi.getPurchased] Purchases query result:', {
        purchases,
        error: purchasesError,
        count: purchases?.length
      });

      if (purchasesError) {
        console.error('[providerLeadsApi.getPurchased] Error fetching purchases:', purchasesError);
        throw purchasesError;
      }
      
      if (!purchases || purchases.length === 0) {
        console.log('[providerLeadsApi.getPurchased] No purchases found, returning empty array');
        return [];
      }

      const leadIds = purchases.map(p => p.lead_id);
      console.log('[providerLeadsApi.getPurchased] Fetching lead details for IDs:', leadIds);

      // Get full lead details for purchased leads
      const { data: leads, error: leadsError } = await supabase
        .from('leads')
        .select('*')
        .in('id', leadIds);

      console.log('[providerLeadsApi.getPurchased] Leads query result:', {
        leads,
        error: leadsError,
        count: leads?.length
      });

      if (leadsError) {
        console.error('[providerLeadsApi.getPurchased] Error fetching leads:', leadsError);
        throw leadsError;
      }
      
      if (!leads) {
        console.log('[providerLeadsApi.getPurchased] No leads found, returning empty array');
        return [];
      }

      // Merge purchase info with lead data
      const result = leads.map(lead => {
        const purchase = purchases.find(p => p.lead_id === lead.id);
        return {
          ...lead,
          purchased_at: purchase?.purchased_at,
          credits_spent: purchase?.credits_spent,
          is_purchased: true,
        };
      }).sort((a, b) => {
        // Sort by purchase date, most recent first
        return new Date(b.purchased_at).getTime() - new Date(a.purchased_at).getTime();
      });
      
      console.log('[providerLeadsApi.getPurchased] Returning', result.length, 'purchased leads');
      return result;
    } catch (error) {
      console.error('[providerLeadsApi.getPurchased] Unexpected error:', error);
      throw error;
    }
  },
};

// Helper functions to blur contact info
function blurEmail(email: string): string {
  const [username, domain] = email.split('@');
  if (!username || !domain) return '***@***.***';
  
  const visibleChars = Math.min(2, Math.floor(username.length / 3));
  const blurred = username.substring(0, visibleChars) + '***';
  return `${blurred}@${domain}`;
}

function blurPhone(phone: string): string {
  // Remove all non-digit characters except +
  const cleaned = phone.replace(/[^\d+]/g, '');
  
  if (cleaned.length < 4) return '***';
  
  // Show country code and first digit, blur the rest
  const countryCode = cleaned.startsWith('+') ? cleaned.substring(0, 3) : '';
  const remaining = cleaned.substring(countryCode.length);
  
  if (remaining.length <= 3) {
    return countryCode + ' ***';
  }
  
  const visible = remaining.substring(0, 1);
  const blurred = '** *** ****';
  
  return `${countryCode} ${visible}${blurred}`;
}

// Admin Analytics API
export const adminAnalyticsApi = {
  getOverview: async () => {
    const { data, error } = await supabase.rpc('get_admin_analytics');
    if (error) throw error;
    return data;
  },
};

// Admin Leads API
export const adminLeadsApi = {
  getAll: async (filters?: { 
    destination?: string; 
    status?: string; 
    personaType?: string;
    startDate?: string; 
    endDate?: string;
  }) => {
    let query = supabase.from('admin_lead_stats').select('*');

    if (filters?.destination && filters.destination !== 'all') {
      query = query.ilike('destination', `%${filters.destination}%`);
    }

    if (filters?.status && filters.status !== 'all') {
      query = query.eq('status', filters.status);
    }

    if (filters?.personaType && filters.personaType !== 'all') {
      query = query.eq('tourist_persona->>type', filters.personaType);
    }

    if (filters?.startDate) {
      query = query.gte('start_date', filters.startDate);
    }

    if (filters?.endDate) {
      query = query.lte('end_date', filters.endDate);
    }

    query = query.order('created_at', { ascending: false });

    const { data, error } = await query;
    if (error) throw error;
    return data || [];
  },

  getById: async (leadId: string) => {
    const { data, error } = await supabase
      .from('admin_lead_stats')
      .select('*')
      .eq('id', leadId)
      .single();
    if (error) throw error;
    return data;
  },

  overridePrice: async (leadId: string, overridePrice: number | null) => {
    const { data, error } = await supabase.rpc('admin_override_lead_price', {
      p_lead_id: leadId,
      p_override_price: overridePrice,
    });
    if (error) throw error;
    return data;
  },

  setStatus: async (leadId: string, status: string) => {
    const { data, error } = await supabase.rpc('admin_set_lead_status', {
      p_lead_id: leadId,
      p_status: status,
    });
    if (error) throw error;
    return data;
  },

  delete: async (leadId: string) => {
    const { error } = await supabase.from('leads').delete().eq('id', leadId);
    if (error) throw error;
  },
};

// Admin Providers API
export const adminProvidersApi = {
  getAll: async () => {
    const { data, error } = await supabase
      .from('admin_provider_stats')
      .select('*')
      .order('created_at', { ascending: false });
    if (error) throw error;
    return data || [];
  },

  getById: async (providerId: string) => {
    const { data, error } = await supabase
      .from('admin_provider_stats')
      .select('*')
      .eq('id', providerId)
      .single();
    if (error) throw error;
    return data;
  },

  adjustCredits: async (providerId: string, amount: number, reason: string) => {
    const { data, error } = await supabase.rpc('admin_adjust_credits', {
      p_provider_id: providerId,
      p_amount: amount,
      p_reason: reason,
    });
    if (error) throw error;
    return data;
  },

  toggleStatus: async (providerId: string, isActive: boolean, adminId: string) => {
    const { data, error } = await supabase.rpc('admin_toggle_provider_status', {
      p_provider_id: providerId,
      p_is_active: isActive,
      p_admin_id: adminId,
    });
    if (error) throw error;
    return data;
  },

  getTransactions: async (providerId: string) => {
    const { data, error } = await supabase
      .from('credit_transactions')
      .select('*')
      .eq('provider_id', providerId)
      .order('created_at', { ascending: false })
      .limit(50);

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

export default {
  places: placesApi,
  trips: tripsApi,
  tripDays: tripDaysApi,
  tripPlaces: tripPlacesApi,
  collections: collectionsApi,
  bookmarks: bookmarksApi,
  businesses: businessesApi,
  siteSettings: siteSettingsApi,
  leads: leadsApi,
  providerServices: providerServicesApi,
  providerWallet: providerWalletApi,
  leadPurchases: leadPurchasesApi,
  providerLeads: providerLeadsApi,
  adminAnalytics: adminAnalyticsApi,
  adminLeads: adminLeadsApi,
  adminProviders: adminProvidersApi,
};

// Auth helper functions
export const authApi = {
  // Check if username is available
  async checkUsernameAvailable(username: string): Promise<boolean> {
    const { data, error } = await supabase
      .from('profiles')
      .select('username')
      .eq('username', username)
      .maybeSingle();

    if (error) {
      console.error('Username check error:', error);
      return false;
    }

    // If data is null, username is available
    return data === null;
  },
};

// Tours API
export const toursApi = {
  // Analyze trip for tour recommendation
  async analyzeTripForTour(tripData: {
    destination: string;
    days: Array<{
      date: string;
      places: Array<{
        name: string;
        type: string;
        lat?: number;
        lng?: number;
        duration?: string;
      }>;
    }>;
    startPoint?: string;
    travelers: number;
    interests: string[];
    tripHasBalloon?: boolean; // Trip-level constraint
  }) {
    const { data, error } = await supabase.functions.invoke('analyze-trip', {
      body: tripData,
    });

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

  // Search tours based on recommendation
  async searchTours(params: {
    destination: string;
    recommended_type: string;
    place_types?: string[];
    travelers?: number;
    daily_tour_slug?: string; // Preferred tour slug from AI
  }) {
    console.log('🔍 API: Searching tours with params:', params);
    
    const { data, error } = await supabase.functions.invoke('search-tours', {
      body: params,
    });

    if (error) {
      console.error('❌ API: Error searching tours:', error);
      throw error;
    }
    
    console.log('✅ API: Tours found:', data?.tours?.length || 0);
    return data?.tours || [];
  },

  // Save tour recommendation
  async saveRecommendation(recommendation: {
    trip_id: string;
    trip_day_id?: string;
    recommend: boolean;
    reason: string;
    recommended_type: string;
    ideal_duration?: string;
    best_time?: string;
    confidence: number;
    why_better_than_self: string[];
    distance_saved_km?: number;
    time_saved_hours?: number;
    logistics_removed?: string[];
    expert_value?: string[];
    traveler_group_type?: string;
    traveler_pace?: string;
    traveler_budget_level?: string;
    daily_tour_slug?: string;
  }) {
    const { data, error } = await supabase
      .from('tour_recommendations')
      .insert([recommendation])
      .select()
      .single();

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

  // Mark recommendation as clicked
  async markRecommendationClicked(recommendationId: string, tourId?: string) {
    const { error } = await supabase
      .from('tour_recommendations')
      .update({
        clicked: true,
        clicked_at: new Date().toISOString(),
        tour_selected_id: tourId,
      })
      .eq('id', recommendationId);

    if (error) throw error;
  },

  // Get tour by ID
  async getTourById(tourId: string) {
    const { data, error } = await supabase
      .from('tours')
      .select('*')
      .eq('id', tourId)
      .maybeSingle();

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

  // Get recommendations for trip
  async getRecommendationsForTrip(tripId: string) {
    const { data, error } = await supabase
      .from('tour_recommendations')
      .select('*')
      .eq('trip_id', tripId)
      .order('created_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Admin: Get all tours
  async getAllTours() {
    const { data, error } = await supabase
      .from('tours')
      .select('*')
      .order('created_at', { ascending: false });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Admin: Create tour
  async createTour(tourData: {
    destination: string;
    name: string;
    type: string;
    covers: string[];
    description?: string;
    duration_hours: number;
    price_from: number;
    price_currency: string;
    commission_rate: number;
    provider_id?: string;
    image_url?: string;
    includes?: string[];
    excludes?: string[];
    meeting_point?: string;
    max_participants?: number;
    min_participants?: number;
    available_days?: string[];
    is_active?: boolean;
  }) {
    const { data, error } = await supabase
      .from('tours')
      .insert([{ ...tourData, is_active: tourData.is_active ?? true }])
      .select()
      .single();

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

  // Admin: Update tour
  async updateTour(tourId: string, tourData: Partial<{
    destination: string;
    name: string;
    type: string;
    covers: string[];
    description?: string;
    duration_hours: number;
    price_from: number;
    price_currency: string;
    commission_rate: number;
    provider_id?: string;
    image_url?: string;
    includes?: string[];
    excludes?: string[];
    meeting_point?: string;
    max_participants?: number;
    min_participants?: number;
    available_days?: string[];
    rating?: number;
    review_count?: number;
    is_active?: boolean;
  }>) {
    const { data, error } = await supabase
      .from('tours')
      .update(tourData)
      .eq('id', tourId)
      .select()
      .single();

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

  // Admin: Delete tour
  async deleteTour(tourId: string) {
    const { error } = await supabase
      .from('tours')
      .delete()
      .eq('id', tourId);

    if (error) throw error;
  },
};

// Daily Tours API
export const dailyToursApi = {
  // Get all active daily tours
  async getAll() {
    const { data, error } = await supabase
      .from('daily_tours')
      .select('*')
      .eq('is_active', true)
      .order('region', { ascending: true });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Get daily tours by region
  async getByRegion(region: string) {
    const { data, error } = await supabase
      .from('daily_tours')
      .select('*')
      .eq('region', region)
      .eq('is_active', true)
      .order('duration_hours', { ascending: true });

    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  // Get daily tour by slug
  async getBySlug(slug: string) {
    const { data, error } = await supabase
      .from('daily_tours')
      .select('*')
      .eq('slug', slug)
      .eq('is_active', true)
      .maybeSingle();

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

// Advanced Admin API
export const adminAdvancedApi = {
  // Get dashboard stats
  async getDashboardStats() {
    const { data, error } = await supabase.rpc('get_admin_dashboard_stats');
    if (error) throw error;
    return data;
  },

  // Get admin logs with pagination
  async getLogs(page = 1, limit = 50, filters?: { action?: string; entity_type?: string }) {
    const from = (page - 1) * limit;
    const to = from + limit - 1;

    let query = supabase
      .from('admin_logs')
      .select('*, profiles!admin_logs_admin_id_fkey(email, full_name)', { count: 'exact' })
      .order('created_at', { ascending: false })
      .range(from, to);

    if (filters?.action) {
      query = query.eq('action', filters.action);
    }
    if (filters?.entity_type) {
      query = query.eq('entity_type', filters.entity_type);
    }

    const { data, error, count } = await query;
    if (error) throw error;

    return {
      logs: Array.isArray(data) ? data : [],
      total: count || 0,
      page,
      totalPages: Math.ceil((count || 0) / limit),
    };
  },

  // Log admin action
  async logAction(action: string, entityType: string, entityId?: string, details?: any) {
    const { data, error } = await supabase.rpc('log_admin_action', {
      p_action: action,
      p_entity_type: entityType,
      p_entity_id: entityId,
      p_details: details || {},
    });
    if (error) throw error;
    return data;
  },

  // Get search history
  async getSearchHistory(page = 1, limit = 20) {
    const from = (page - 1) * limit;
    const to = from + limit - 1;

    const { data, error, count } = await supabase
      .from('admin_search_history')
      .select('*', { count: 'exact' })
      .order('created_at', { ascending: false })
      .range(from, to);

    if (error) throw error;

    return {
      searches: Array.isArray(data) ? data : [],
      total: count || 0,
      page,
      totalPages: Math.ceil((count || 0) / limit),
    };
  },

  // AI Search
  async aiSearch(query: string, conversationHistory: any[] = []) {
    const { data, error } = await supabase.functions.invoke('ai-search', {
      body: { query, conversationHistory },
    });

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

  // Smart Search
  async smartSearch(params: {
    query: string;
    count?: number;
    offset?: number;
    safeSearch?: string;
    freshness?: string;
    mkt?: string;
    cc?: string;
  }) {
    const { data, error } = await supabase.functions.invoke('smart-search', {
      body: params,
    });

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

  // Generate Image
  async generateImage(contents: any[]) {
    const { data, error } = await supabase.functions.invoke('generate-image', {
      body: { contents },
    });

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

  // Query Image Task
  async queryImageTask(taskId: string) {
    const { data, error } = await supabase.functions.invoke('query-image-task', {
      body: { taskId },
    });

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

  // Get admin images
  async getImages(page = 1, limit = 20, filters?: { generation_method?: string; tags?: string[] }) {
    const from = (page - 1) * limit;
    const to = from + limit - 1;

    let query = supabase
      .from('admin_images')
      .select('*, profiles!admin_images_uploaded_by_fkey(email, full_name)', { count: 'exact' })
      .order('created_at', { ascending: false })
      .range(from, to);

    if (filters?.generation_method) {
      query = query.eq('generation_method', filters.generation_method);
    }
    if (filters?.tags && filters.tags.length > 0) {
      query = query.contains('tags', filters.tags);
    }

    const { data, error, count } = await query;
    if (error) throw error;

    return {
      images: Array.isArray(data) ? data : [],
      total: count || 0,
      page,
      totalPages: Math.ceil((count || 0) / limit),
    };
  },

  // Save generated image
  async saveImage(imageData: {
    title: string;
    description?: string;
    file_path: string;
    file_size?: number;
    mime_type?: string;
    width?: number;
    height?: number;
    generation_method: 'upload' | 'ai_generated';
    generation_prompt?: string;
    tags?: string[];
  }) {
    const { data, error } = await supabase
      .from('admin_images')
      .insert({
        ...imageData,
        uploaded_by: (await supabase.auth.getUser()).data.user?.id,
      })
      .select()
      .single();

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

  // Delete image
  async deleteImage(id: string) {
    const { error } = await supabase.from('admin_images').delete().eq('id', id);
    if (error) throw error;
  },

  // Update image
  async updateImage(id: string, updates: Partial<{
    title: string;
    description: string;
    tags: string[];
  }>) {
    const { data, error } = await supabase
      .from('admin_images')
      .update(updates)
      .eq('id', id)
      .select()
      .single();

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

  // Get analytics data
  async getAnalytics(params: {
    metric_name?: string;
    period?: string;
    start_date?: string;
    end_date?: string;
  }) {
    let query = supabase
      .from('admin_analytics')
      .select('*')
      .order('period_start', { ascending: false });

    if (params.metric_name) {
      query = query.eq('metric_name', params.metric_name);
    }
    if (params.period) {
      query = query.eq('period', params.period);
    }
    if (params.start_date) {
      query = query.gte('period_start', params.start_date);
    }
    if (params.end_date) {
      query = query.lte('period_end', params.end_date);
    }

    const { data, error } = await query;
    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },
  // API Keys
  async getApiKeys() {
    const { data, error } = await supabase
      .from('admin_api_keys')
      .select('*')
      .order('key', { ascending: true });
    if (error) throw error;
    return Array.isArray(data) ? data : [];
  },

  async updateApiKey(key: string, value: string, description?: string) {
    const { data: existing } = await supabase
      .from('admin_api_keys')
      .select('id')
      .eq('key', key)
      .maybeSingle();

    if (existing) {
      const { data, error } = await supabase
        .from('admin_api_keys')
        .update({ value, description, updated_at: new Date().toISOString() })
        .eq('key', key)
        .select()
        .single();
      if (error) throw error;
      return data;
    } else {
      const { data, error } = await supabase
        .from('admin_api_keys')
        .insert({ key, value, description })
        .select()
        .single();
      if (error) throw error;
      return data;
    }
  },

  async deleteApiKey(key: string) {
    const { error } = await supabase
      .from('admin_api_keys')
      .delete()
      .eq('key', key);
    if (error) throw error;
  },

};
