import time
import json
import certifi
import cloudscraper
import random
import sys
import requests
import threading
from fake_useragent import UserAgent


# API URL'leri
BOOKING_URL = "Api1"
ACCEPT_URL = "Api2"
# API'ye gönderilecek login bilgileri
LOGIN_HASH = "Hash1"
ACCEPT_LOGIN_HASH = "Hash2"
# Araç ID
VEHICLE_ID = "36979"
# Telegram Bot API Bilgileri
TELEGRAM_BOT_TOKEN = "Token"
TELEGRAM_CHAT_ID = "id
# Proxy listesi
proxy_list = [
    {"Proxy"},
    {"Proxy "},
    {"Proxy "},
    {"Proxy "},
  
    
]
# CloudScraper başlat
scraper = cloudscraper.create_scraper(
    browser={"browser": "chrome", "platform": "windows", "mobile": False}
)
previous_hashes = set()
# Yeniden deneme ayarları
MAX_RETRIES = 5
RETRY_DELAY = 3
# Başarılı istek sayacı
success_count = 0
lock = threading.Lock()  # Thread güvenliği için kilitleme mekanizması
def get_random_headers():
    """Her istek için rastgele User-Agent döndürür"""
    ua = UserAgent()
    return {
        "Content-Type": "application/json",
        "User-Agent": ua.random
    }
def send_telegram_message(message):
    """Telegram'a mesaj gönderen fonksiyon"""
    url = f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage"
    payload = {"chat_id": TELEGRAM_CHAT_ID, "text": message}
    try:
        response = requests.post(url, json=payload)
        if response.status_code == 200:
            print("\n📩 Telegram bildirimi gönderildi!")
        else:
            print(f"\n❌ Telegram hata kodu: {response.status_code} - {response.text}")
    except Exception as e:
        print(f"\n⚠️ Telegram bağlantı hatası: {e}")
def accept_booking(booking_hash):
    """Rezervasyonu kabul eden fonksiyon (Thread ile çalışır)"""
    global previous_hashes
    if booking_hash in previous_hashes:
        return  # Aynı rezervasyonu iki kez işlememek için
    print(f"\n🚀 Yeni Rezervasyon İşleniyor! Booking Hash: {booking_hash}")
    accept_payload = {
        "login_hash": ACCEPT_LOGIN_HASH,
        "booking_hash": booking_hash,
        "vehicle_id": VEHICLE_ID,
        "refuse": "accept"
    }
    proxies = random.choice(proxy_list)  # Her istek için farklı proxy
    headers = get_random_headers()  # Her istek için farklı User-Agent
    for attempt in range(MAX_RETRIES):
        try:
            accept_response = scraper.post(ACCEPT_URL, headers=headers, json=accept_payload, verify=certifi.where(), proxies=proxies)
            if accept_response.status_code == 200:
                with lock:
                    previous_hashes.add(booking_hash)  # Önceki rezervasyonlara ekle
                print(f"\n✅ Rezervasyon kabul edildi! {booking_hash}")
                # Telegram bildirimi gönder
                send_telegram_message(f"✅ Rezervasyon Kabul Edildi! ✅\n\n{booking_hash})")
                break
            else:
                print(f"\n❌ Rezervasyon kabul hatası: {accept_response.status_code} - {accept_response.text}")
                time.sleep(RETRY_DELAY * (2 ** attempt))  # Exponential backoff
        except Exception as e:
            print(f"\n⚠️ Bağlantı hatası (Rezervasyon kabulü): {e}, tekrar deneniyor...")
            time.sleep(RETRY_DELAY * (2 ** attempt))  # Exponential backoff
def check_new_bookings(response):
    """Yeni rezervasyonları kontrol edip, işleme alan fonksiyon"""
    try:
        current_data = response.json().get("data", {}).get("bookings", [])
    except json.JSONDecodeError as e:
        print(f"\n❌ JSON dönüşüm hatası: {e}. Yanıt içeriği: {response.text}")
        return
    # Thread havuzu oluştur - aynı anda birden fazla rezervasyon için
    accept_threads = []
    
    for booking in current_data:
        booking_hash = booking["booking_hash_link"]
        if booking_hash not in previous_hashes:
            # Yeni rezervasyonlar için hemen işlem başlat
            thread = threading.Thread(target=accept_booking, args=(booking_hash,))
            thread.daemon = True
            thread.start()
            accept_threads.append(thread)
            
            # Diğer rezervasyonlara geçerken kısa bekle
            time.sleep(0.05)
    
    # Tüm rezervasyon işlemleri tamamlanana kadar bekle (opsiyonel)
    # for thread in accept_threads:
    #     thread.join(timeout=5)  # 5 saniye bekle
def send_booking_request():
    """Rezervasyonları takip eden ana fonksiyon"""
    global success_count  # Global sayaç
    
    # Thread havuzu oluştur - çoklu istekler için
    max_threads = 5  # Aynı anda gönderilecek maksimum istek sayısı
    request_threads = []
    while True:
        # Eğer aktif thread sayısı maksimumdan azsa yeni threadler ekle
        active_threads = sum(1 for t in request_threads if t.is_alive())
        new_threads_needed = max_threads - active_threads
        
        for _ in range(new_threads_needed):
            thread = threading.Thread(target=send_single_request)
            thread.daemon = True  # Ana program sonlandığında thread de sonlanır
            thread.start()
            request_threads.append(thread)
        
        # Bitmiş threadleri listeden temizle
        request_threads = [t for t in request_threads if t.is_alive()]
        
        # Kısa bir bekleme ile CPU kullanımını dengele
        time.sleep(0.1)
def send_single_request():
    """Tek bir rezervasyon isteği gönderir"""
    global success_count, lock
    
    proxies = random.choice(proxy_list)  # Her istek için farklı proxy
    headers = get_random_headers()  # Her istek için farklı User-Agent
    for attempt in range(MAX_RETRIES):
        try:
            payload = {"login_hash": LOGIN_HASH}
            response = scraper.post(BOOKING_URL, headers=headers, json=payload, verify=certifi.where(), proxies=proxies)
            if response.status_code == 200:
                with lock:
                    success_count += 1  # Sayacı artır
                sys.stdout.write(f"\r✅ Başarılı istek sayısı: {success_count}")  # Aynı satıra yaz
                sys.stdout.flush()  # Terminali güncelle
                check_new_bookings(response)
                break  # Başarılıysa döngüden çık
            else:
                print(f"\n❌ Hata: {response.status_code} - {response.text}")
                time.sleep(RETRY_DELAY * (2 ** attempt))  # Exponential backoff
        except Exception as e:
            print(f"\n⚠️ Bağlantı hatası: {e}, tekrar deneniyor...")
            time.sleep(RETRY_DELAY * (2 ** attempt))  # Exponential backoff
# Sürekli çalıştır
send_booking_request()