import streamlit as st
import pandas as pd
import time
import urllib.parse
import io
import re
from webdriver_manager.chrome import ChromeDriverManager
from selenium import webdriver
from selenium.webdriver.common.by import By

st.set_page_config(
    page_title="Google Maps Canlı Esnaf & Lead Bulucu",
    page_icon="📍",
    layout="wide"
)

st.title("📍 Google Maps Canlı Esnaf & Lead Bulucu")
st.markdown("Google Maps'ten canlı esnaf verilerini tarar, **sadece cep telefonlu (05xx)** işletmeleri ayıklar ve tek tıkla **WhatsApp mesajı** göndermenizi sağlar.")

# Arama Formu
col1, col2, col3, col4 = st.columns([2, 2, 2, 2])
with col1:
    city = st.text_input("İl", value="Mersin", placeholder="Örn: Mersin")
with col2:
    district = st.text_input("İlçe", value="Akdeniz", placeholder="Örn: Akdeniz")
with col3:
    category = st.text_input("Sektör / Kriter", value="Güzellik Salonu", placeholder="Örn: Güzellik Salonu, Kuaför, Tesisatçı")
with col4:
    target_count = st.number_input("Taranacak İşletme Sayısı", min_value=5, max_value=200, value=50, step=5)

col_f1, col_f2 = st.columns(2)
with col_f1:
    only_mobile_phone = st.checkbox("📱 Sadece Cep Telefonu (05xx) Olanları Listele (Sabit hatlar elensin)", value=True)
with col_f2:
    only_no_website = st.checkbox("🌐 Sadece Web Sitesi OLMAYAN esnafları listele", value=False)

# WhatsApp Mesaj Şablonu Alanı
with st.expander("💬 WhatsApp Mesaj Şablonu Ayarı", expanded=True):
    wp_template = st.text_area(
        "Her esnafa tek tıkla iletilecek hazır taslak mesajınız (İşletme adı için {isletme} yazabilirsiniz):",
        value="Merhaba {isletme}, Google Haritalar'da web sitenizin bulunmadığını fark ettik. İşletmeniz için profesyonel web sitesi ve dijital çözümlerimiz hakkında bilgi almak ister misiniz?",
        height=85
    )

def extract_mobile_phone(text):
    """
    Sadece Türk cep telefonu numaralarını (05XX XXX XX XX) ayıklar.
    0322, 0324, 0212 gibi alan kodlu sabit hatları, 0850 ve 444'lü hatları KESİNLİKLE eler.
    """
    if not text:
        return None
    m = re.search(r'(?:\+?90\s*|\(0|\(0090\)|0)?\s*\(?(5\d{2})\)?[\s.-]?(\d{3})[\s.-]?(\d{2})[\s.-]?(\d{2})', text)
    if m:
        return f"0{m.group(1)} {m.group(2)} {m.group(3)} {m.group(4)}"
    return None

def create_whatsapp_link(phone, business_name, template):
    if not phone or phone == "Yok":
        return ""
    digits = re.sub(r'\D', '', phone)
    if digits.startswith('0'):
        digits = digits[1:]
    elif digits.startswith('90'):
        digits = digits[2:]
        
    if len(digits) == 10 and digits.startswith('5'):
        full_phone = f"90{digits}"
        custom_msg = template.replace("{isletme}", business_name).replace("{isletme_adi}", business_name)
        encoded_msg = urllib.parse.quote(custom_msg, safe='', encoding='utf-8')
        return f"https://api.whatsapp.com/send/?phone={full_phone}&text={encoded_msg}"
    return ""

def scrape_google_maps(category, district, city, max_results=50, filter_mobile_only=True, progress_callback=None):
    query = f"{category} {district} {city}"
    search_url = f"https://www.google.com/maps/search/{urllib.parse.quote(query)}"
    
    driver_path = ChromeDriverManager().install()
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_argument('--window-size=1920,1080')
    options.add_argument('--lang=tr-TR')
    prefs = {"profile.managed_default_content_settings.images": 2}
    options.add_experimental_option("prefs", prefs)
    
    driver = webdriver.Chrome(executable_path=driver_path, options=options)
    
    results = []
    try:
        if progress_callback:
            progress_callback(0.05, f"Google Maps'te '{query}' araması açılıyor...")
        
        driver.get(search_url)
        time.sleep(4)
        
        feed = None
        for xpath in [
            '//div[@role="feed"]',
            '//div[contains(@aria-label, "Sonuçlar")]',
            '//div[contains(@aria-label, "Results")]'
        ]:
            elems = driver.find_elements(By.XPATH, xpath)
            if elems:
                feed = elems[0]
                break

        scroll_attempts = 0
        max_scrolls = max(25, int(max_results * 0.8))
        last_count = 0
        stuck_count = 0
        
        while scroll_attempts < max_scrolls:
            cards = driver.find_elements(By.XPATH, '//div[contains(@class, "Nv2PK")]')
            current_count = len(cards)
            
            if progress_callback and scroll_attempts % 3 == 0:
                progress_callback(0.1, f"Google Maps taranıyor... ({current_count}/{max_results} işletme yüklendi)")
                
            if current_count >= max_results:
                break
                
            if current_count == last_count:
                stuck_count += 1
                if stuck_count >= 5:
                    break
            else:
                stuck_count = 0
                
            last_count = current_count
            if feed:
                driver.execute_script("arguments[0].scrollTop = arguments[0].scrollHeight;", feed)
            else:
                driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
            time.sleep(1.0)
            scroll_attempts += 1

        cards = driver.find_elements(By.XPATH, '//div[contains(@class, "Nv2PK")]')
        total_found = min(len(cards), max_results)
        
        if progress_callback:
            progress_callback(0.2, f"Google Maps'te {total_found} işletme listelendi. Detaylar ve cep telefonları taranıyor...")

        for idx in range(total_found):
            try:
                current_cards = driver.find_elements(By.XPATH, '//div[contains(@class, "Nv2PK")]')
                if idx >= len(current_cards):
                    break
                card = current_cards[idx]
                
                title_elem = card.find_element(By.XPATH, './/a[contains(@class, "hfpxzc")]')
                name = title_elem.get_attribute("aria-label") or "İsimsiz İşletme"
                maps_url = title_elem.get_attribute("href") or ""
                
                card_text = card.text
                rating = ""
                reviews_count = ""
                for line in card_text.split('\n'):
                    if '(' in line and ')' in line and (',' in line or '.' in line):
                        parts = line.split('(')
                        rating = parts[0].strip().replace('\ue88e', '').replace('', '')
                        reviews_count = parts[1].replace(')', '').strip().replace('\ue88e', '').replace('', '')
                        break

                mobile_phone = extract_mobile_phone(card_text)

                website = ""
                try:
                    web_btn = card.find_element(By.XPATH, './/a[contains(@aria-label, "web sitesi") or contains(@aria-label, "website")]')
                    website = web_btn.get_attribute("href") or ""
                except Exception:
                    pass

                driver.execute_script("arguments[0].click();", title_elem)
                time.sleep(0.8)
                
                address = ""
                info_elems = driver.find_elements(By.XPATH, '//button[contains(@aria-label, ":")] | //a[contains(@aria-label, ":")]')
                for elem in info_elems:
                    aria = elem.get_attribute("aria-label") or ""
                    if aria.startswith("Adres:"):
                        address = aria.replace("Adres:", "").strip()
                    elif aria.startswith("Telefon:") and not mobile_phone:
                        raw_phone = aria.replace("Telefon:", "").strip()
                        mobile_phone = extract_mobile_phone(raw_phone)
                    elif aria.startswith("Web sitesi:") and not website:
                        website = elem.get_attribute("href") or aria.replace("Web sitesi:", "").strip()

                if filter_mobile_only and not mobile_phone:
                    continue

                wp_link = create_whatsapp_link(mobile_phone, name, wp_template)

                results.append({
                    "İşletme Adı": name,
                    "Cep Telefonu": mobile_phone if mobile_phone else "Yok",
                    "WhatsApp Mesaj": wp_link,
                    "Gerçek Adres": address if address else f"{district} / {city}",
                    "Web Sitesi": website,
                    "Puan": rating if rating else "-",
                    "Yorum Sayısı": reviews_count if reviews_count else "-",
                    "Google Maps Linki": maps_url
                })

                if progress_callback:
                    pct = 0.2 + 0.8 * ((idx + 1) / total_found)
                    status_phone = mobile_phone if mobile_phone else "Sabit/Yok"
                    web_status = "Var" if website else "YOK ❌"
                    progress_callback(min(pct, 1.0), f"[{idx+1}/{total_found}] {name} (Cep: {status_phone} | Web: {web_status})")

            except Exception:
                continue

    finally:
        driver.quit()

    df = pd.DataFrame(results)
    if not df.empty:
        df = df.drop_duplicates(subset=["İşletme Adı"])
    return df

search_button = st.button("🚀 Google Maps'ten Canlı Tara", type="primary", use_container_width=True)

if search_button:
    if not city or not category:
        st.warning("Lütfen İl ve Sektör alanlarını doldurun.")
    else:
        progress_bar = st.progress(0)
        status_text = st.empty()

        def update_progress(val, text):
            progress_bar.progress(val)
            status_text.text(text)

        start_time = time.time()
        df = scrape_google_maps(
            category=category,
            district=district,
            city=city,
            max_results=int(target_count),
            filter_mobile_only=only_mobile_phone,
            progress_callback=update_progress
        )
        elapsed = round(time.time() - start_time, 1)

        progress_bar.progress(1.0)
        status_text.empty()

        if not df.empty:
            if only_no_website:
                filtered_df = df[df["Web Sitesi"] == ""].copy()
            else:
                filtered_df = df.copy()

            no_web_count = len(filtered_df[filtered_df["Web Sitesi"] == ""])
            st.success(f"🎉 **{elapsed} saniyede** toplam **{len(filtered_df)}** adet cep telefonlu esnaf ayıklandı. **{no_web_count}** tanesinin **WEB SİTESİ YOK!**")

            # Tablo Gösterimi
            st.dataframe(
                filtered_df,
                column_config={
                    "WhatsApp Mesaj": st.column_config.LinkColumn("WhatsApp 💬", display_text="Mesaj Gönder 💬"),
                    "Google Maps Linki": st.column_config.LinkColumn("Harita Linki", display_text="Haritada Gör 📍"),
                    "Web Sitesi": st.column_config.LinkColumn("Web Sitesi", display_text=None),
                    "Cep Telefonu": st.column_config.TextColumn("Cep Telefonu (05xx)")
                },
                use_container_width=True,
                height=520
            )

            col_down1, col_down2 = st.columns(2)

            # Excel İndir (.xlsx)
            buffer = io.BytesIO()
            with pd.ExcelWriter(buffer, engine='openpyxl') as writer:
                filtered_df.to_excel(writer, index=False, sheet_name='CepTelefonluEsnaflar')
            excel_data = buffer.getvalue()

            with col_down1:
                st.download_button(
                    label="📥 Excel Olarak İndir (.xlsx)",
                    data=excel_data,
                    file_name=f"google_maps_{category}_{district}_{city}_cep_ve_whatsapp.xlsx",
                    mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                    use_container_width=True
                )

            # CSV İndir (.csv)
            csv_data = filtered_df.to_csv(index=False).encode('utf-8-sig')
            with col_down2:
                st.download_button(
                    label="📥 CSV Olarak İndir (.csv)",
                    data=csv_data,
                    file_name=f"google_maps_{category}_{district}_{city}_cep_ve_whatsapp.csv",
                    mime="text/csv",
                    use_container_width=True
                )
        else:
            st.warning("Arama kriterlerine uygun veya cep telefonu kayıtlı işletme bulunamadı. Taranacak işletme sayısını artırıp tekrar deneyebilirsiniz.")
