-- Anonim geziler için token sistemi ekle
-- Bu migration güvenlik açığını kapatır

-- 1. trips tablosuna anonymous_token sütunu ekle
ALTER TABLE trips ADD COLUMN IF NOT EXISTS anonymous_token TEXT;

-- 2. Unique index oluştur (NULL değerler için unique constraint çalışmaz, bu yüzden partial index)
CREATE UNIQUE INDEX IF NOT EXISTS trips_anonymous_token_key 
  ON trips(anonymous_token) 
  WHERE anonymous_token IS NOT NULL;

-- 3. Index oluştur (performans için)
CREATE INDEX IF NOT EXISTS trips_anonymous_token_idx 
  ON trips(anonymous_token) 
  WHERE anonymous_token IS NOT NULL;

-- 4. Eski güvensiz politikaları kaldır
DROP POLICY IF EXISTS "Herkes public seyahatleri görebilir" ON trips;
DROP POLICY IF EXISTS "Kullanıcılar kendi seyahatlerini güncelleyebilir" ON trips;
DROP POLICY IF EXISTS "Kullanıcılar kendi seyahatlerini silebilir" ON trips;

-- 5. Yeni güvenli politikalar oluştur

-- SELECT: Public geziler, kendi gezileri, veya token ile anonim geziler
CREATE POLICY "Güvenli seyahat görüntüleme"
  ON trips FOR SELECT
  USING (
    is_public = true 
    OR user_id = auth.uid()
    OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
  );

-- UPDATE: Sadece kendi gezileri veya token ile anonim geziler
CREATE POLICY "Güvenli seyahat güncelleme"
  ON trips FOR UPDATE
  USING (
    user_id = auth.uid()
    OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
  );

-- DELETE: Sadece kendi gezileri veya token ile anonim geziler
CREATE POLICY "Güvenli seyahat silme"
  ON trips FOR DELETE
  USING (
    user_id = auth.uid()
    OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
  );

-- 6. trip_days için güvenli politikalar
DROP POLICY IF EXISTS "Herkes seyahat günlerini yönetebilir" ON trip_days;

CREATE POLICY "Güvenli seyahat günleri yönetimi"
  ON trip_days FOR ALL
  USING (
    EXISTS (
      SELECT 1 FROM trips 
      WHERE trips.id = trip_days.trip_id 
      AND (
        trips.is_public = true
        OR trips.user_id = auth.uid()
        OR (trips.user_id IS NULL AND trips.anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
      )
    )
  );

-- 7. trip_places için güvenli politikalar
DROP POLICY IF EXISTS "Herkes seyahat yerlerini yönetebilir" ON trip_places;

CREATE POLICY "Güvenli seyahat yerleri yönetimi"
  ON trip_places FOR ALL
  USING (
    EXISTS (
      SELECT 1 FROM trip_days 
      JOIN trips ON trips.id = trip_days.trip_id 
      WHERE trip_days.id = trip_places.trip_day_id 
      AND (
        trips.is_public = true
        OR trips.user_id = auth.uid()
        OR (trips.user_id IS NULL AND trips.anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
      )
    )
  );

-- 8. Anonim gezi sahipliğini transfer etme fonksiyonu
CREATE OR REPLACE FUNCTION claim_anonymous_trip(
  trip_id_param UUID,
  token_param TEXT
)
RETURNS BOOLEAN
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
  current_user_id UUID;
BEGIN
  -- Mevcut kullanıcıyı al
  current_user_id := auth.uid();
  
  -- Kullanıcı giriş yapmamışsa hata
  IF current_user_id IS NULL THEN
    RAISE EXCEPTION 'Kullanıcı giriş yapmamış';
  END IF;
  
  -- Token eşleşiyorsa ve user_id NULL ise ownership transfer et
  UPDATE trips
  SET 
    user_id = current_user_id,
    anonymous_token = NULL  -- Token'ı temizle
  WHERE 
    id = trip_id_param
    AND user_id IS NULL
    AND anonymous_token = token_param;
  
  -- Güncelleme başarılı mı kontrol et
  RETURN FOUND;
END;
$$;

-- 9. Eski anonim gezileri temizleme fonksiyonu
CREATE OR REPLACE FUNCTION cleanup_old_anonymous_trips()
RETURNS INTEGER
LANGUAGE plpgsql
SECURITY DEFINER
AS $$
DECLARE
  deleted_count INTEGER;
BEGIN
  -- 7 günden eski, user_id NULL olan gezileri sil
  WITH deleted AS (
    DELETE FROM trips
    WHERE 
      user_id IS NULL
      AND created_at < NOW() - INTERVAL '7 days'
    RETURNING id
  )
  SELECT COUNT(*) INTO deleted_count FROM deleted;
  
  RETURN deleted_count;
END;
$$;

-- 10. Fonksiyonlara yorum ekle
COMMENT ON FUNCTION claim_anonymous_trip IS 'Anonim bir geziyi giriş yapmış kullanıcıya transfer eder';
COMMENT ON FUNCTION cleanup_old_anonymous_trips IS '7 günden eski anonim gezileri siler';
