import re
import time
import requests

from bs4 import BeautifulSoup

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


search_url  = f"https://auto.ria.com/bff/search/public/search?page=0&langId=4&device=desktop-web&search_type=1&mileage%5B0%5D=0&abroad=0&customs_cleared=1&republished_last=2&onlyItems=1"

headers_search   = {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Accept-Language": "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7",
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36"
}


response = requests.get(
    search_url,
    headers=headers_search 
)

options = webdriver.ChromeOptions()
# options.add_argument('--headless')
options.add_argument('--ignore-certificate-errors')  # Игнорирует ошибки сертификата
driver = webdriver.Chrome(options=options)

if response.status_code == 200:
    data = response.json()  # data – это список объявлений
    for item in data:
        # Получаем данные объявления из ключа "component" → "advertisementCard" → "data"
        ad_data = item.get("component", {}).get("advertisementCard", {}).get("data", {})
        if not ad_data:
            continue
        
        # Извлекаем id объявления (числовой id, например: 38045790)
        ad_id = ad_data.get("id", "N/A")
        
        # Извлекаем название. В некоторых случаях title может быть словарем с ключом "content"
        title_field = ad_data.get("title", {})
        if isinstance(title_field, dict):
            name = title_field.get("content", "")
        else:
            name = title_field
        
        # Ищем год выпуска (4-значное число, начинающееся с 19 или 20)
        year_match = re.search(r'\b(19|20)\d{2}\b', name)
        year = year_match.group(0) if year_match else "N/A"
        
        # Цена в долларах (из поля price.USD)
        price = ad_data.get("price", {})
        usd_price = price.get("USD", "N/A")
        
        # Время публикации и ссылка на объявление
        publish_time = ad_data.get("publishTime", "N/A")
        link = ad_data.get("link", "N/A")
        
        # == Получение номера телефона ==
        driver.get(link)
        WebDriverWait(driver, 15).until(EC.presence_of_element_located((By.TAG_NAME, "body")))

        last_height = driver.execute_script("return document.documentElement.scrollHeight")
        for _ in range(5):
            driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);")
            time.sleep(1)
            new_height = driver.execute_script("return document.documentElement.scrollHeight")
            if new_height == last_height:
                break
            last_height = new_height

        # Ищем кнопку "Показати телефон" через относительные селекторы
        button_clicked = False
        phone_button_selectors = [
            (By.XPATH, "//button[contains(@class, 'phone_show')]"),
            (By.XPATH, "//button[contains(@class, 'phones_show')]"),
            (By.CSS_SELECTOR, "[data-action='showPhones']"),
            (By.CSS_SELECTOR, "[data-action='show-phone']"),
            (By.XPATH, "//button[contains(text(), 'Показати телефон')]"),
            (By.XPATH, "//button[contains(text(), 'Показать телефон')]"),
            (By.CSS_SELECTOR, "button.show-phones"),
            (By.CSS_SELECTOR, ".show-phones"),
        ]
        driver.implicitly_wait(0)
        for sel_type, sel_value in phone_button_selectors:
            try:
                btn = driver.find_element(sel_type, sel_value)
                if btn.is_displayed():
                    driver.execute_script("arguments[0].click();", btn)
                    button_clicked = True
                    break
            except Exception:
                continue
        if not button_clicked:
            try:
                btn = WebDriverWait(driver, 10).until(
                    EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'phone')]"))
                )
                btn.click()
                button_clicked = True
            except Exception:
                pass
        driver.implicitly_wait(10)

        if button_clicked:
            try:
                WebDriverWait(driver, 10).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, ".popup-successful-call"))
                )
            except Exception:
                pass

        page_html = driver.page_source
        soup = BeautifulSoup(page_html, 'html.parser')

        all_phones = []
        for a_tag in soup.select("a[href^='tel:']"):
            phone_text = a_tag.get_text(strip=True)
            if phone_text and any(c.isdigit() for c in phone_text) and len(phone_text) > 5:
                all_phones.append(phone_text)
        for div in soup.select(".popup-successful-call-desk"):
            phone_text = div.get_text(strip=True)
            if phone_text and any(c.isdigit() for c in phone_text) and len(phone_text) > 5:
                all_phones.append(phone_text)
        if not all_phones:
            page_text = soup.get_text()
            found = re.findall(r'\+?\d[\d\s\-\(\)]{7,}', page_text)
            for candidate in found:
                cleaned = re.sub(r'\D', '', candidate)
                if cleaned.startswith('380') and len(cleaned) == 12:
                    all_phones.append(candidate.strip())
        all_phones = list(dict.fromkeys(all_phones))
        if not all_phones:
            print("Элемент с номером телефона не найден")
        
        print("ID:", ad_id)
        print("Name:", name)
        print("Год выпуска:", year)
        print("Цена (USD):", usd_price)
        print("publishTime:", publish_time)
        print("Найденные номера:", all_phones)
        print("Link:", link)
        print("-" * 40)
else:
    print("Ошибка, статус код:", response.status_code)




# === Старт парсинга ===
# @router.callback_query(F.data == "startparsing")
# async def startparsing(call: CallbackQuery, state: FSMContext):
#     # Удаляем предыдущее сообщение
#     await call.message.delete()

#     # Отправляем уведомление о запуске парсинга
#     await call.answer("Запуск парсинга", show_alert=False)

#     options = webdriver.ChromeOptions()
#     options.add_argument('--headless')
#     options.add_argument('--ignore-certificate-errors')  # Игнорирует ошибки сертификата
#     driver = webdriver.Chrome(options=options)


#     user_id = int(call.from_user.id)
#     # Получаем настройки фильтра для пользователя из БД
#     filter_settings = await get_filter_settings_dict(user_id)

#     if not filter_settings:
#         await call.message.answer("Настройки фильтра не найдены. Пожалуйста, настройте фильтр.")
#         return

#     # Подставляем значения, если они не указаны, выводим "Не указано"
#     typeavto = filter_settings.get("typeavto") or "1"
#     region_id = filter_settings.get("region_id") or 0
#     year_first = filter_settings.get("year_first") or "0"
#     year_second = filter_settings.get("year_second") or "0"
#     price_first = filter_settings.get("price_first") or "0"
#     price_second = filter_settings.get("price_second") or "0"

#     # Если для регионов предполагается список, можно преобразовать его в строку
#     if isinstance(region_id, list):
#         region_value = int(region_id[0]) if region_id and str(region_id[0]).isdigit() else 0
#         region_str = ", ".join(str(r) for r in region_id)
#     else:
#         try:
#             region_value = int(region_id)
#         except ValueError:
#             region_value = 0
#         region_str = str(region_id)

#     result_text = (
#         "<b>Парсинг запущен с настройками:</b>\n\n"
#         f"Тип авто: {typeavto}\n"
#         f"Регионы: {region_str}\n"
#         f"Годы: {year_first} - {year_second}\n"
#         f"Цена: {price_first} - {price_second}\n"
#     )
#     await call.message.answer(result_text)
    
#     # Вызываем функцию поиска с расширенными параметрами,
#     # Приводим значения к нужным типам (тип авто предполагается числовым, как и цена и года)
#     try:
#         search_result = await search_extended(
#             year_from=str(year_first),
#             year_to=str(year_second),
#             category=int(typeavto) if str(typeavto).isdigit() else 1,
#             region=region_value,
#             price_first=float(price_first),
#             price_second=float(price_second),
#             bodystyle=[]  # Если есть фильтр по кузову, можно его передать
#         )
        
        
#         # Собираем информацию в строку
#         output = ""
#         # Ищем блок с объявлениями
#         items_section = None
#         for template in search_result.get('templates', []):
#             if template.get('id') == 'items':
#                 items_section = template
#                 break

#         if not items_section:
#             await call.message.answer("Объявления не найдены")
#             return

#         for ad in items_section.get('templates', []):
#             try:
#                 # == Получение номера телефона ==
#                 info = extract_car_info(ad)
                
#                 driver.get(info.get('link'))
#                 time.sleep(12)
#                 last_height = driver.execute_script("return document.documentElement.scrollHeight")
                
#                 while True:
#                     driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight);")
#                     time.sleep(2)  # ожидание подгрузки контента
#                     new_height = driver.execute_script("return document.documentElement.scrollHeight")
#                     if new_height == last_height:
#                         break
#                     last_height = new_height
                
#                 try:
#                     # Ждем, пока кнопка "Call" станет кликабельной, и кликаем по ней
#                     driver.find_element(By.XPATH, '/html/body/div/main/div[1]/div[2]/div[2]/div[3]/div[5]/button').click()
#                 except:
#                     driver.find_element(By.XPATH, '/html/body/div[7]/div[10]/div[4]/main/div[12]/div/div[1]/div/a').click()

#                 time.sleep(4)

#                 page_html = driver.page_source
#                 soup = BeautifulSoup(page_html, 'html.parser')

#                 # Извлекаем элемент с номером телефона
#                 phone_links = soup.find_all('a', class_='popup-successful-call')

#                 if phone_links:
#                     # # Найдем все ссылки с номерами телефона по классу popup-successful-call
#                     # phone_links = soup.find_all('a', class_='popup-successful-call')
#                     # phones_from_links = [link.get_text(strip=True) for link in phone_links]

#                     # Также можем собрать номера из элементов div с классом popup-successful-call-desk
#                     phone_divs = soup.find_all('div', class_='popup-successful-call-desk')
#                     phones_from_divs = [div.get_text(strip=True) for div in phone_divs]

#                     # Объединяем результаты
#                     all_phones = phones_from_divs
#                 else:
#                     print("Элемент с номером телефона не найден")
                
                
#                 output += f"ID: {info.get('id')}\n"
#                 output += f"Name: {info.get('name')}\n"
#                 output += f"Год выпуска: {info.get('year') or 'Не указан'}\n"
#                 output += f"Цена (USD): {info.get('price_usd')}\n"
#                 output += f"publishTime: {info.get('publish_time')}\n"
#                 output += f"Номер телефона: {all_phones}\n"
#                 output += f"Link: {info.get('link')}\n"
#                 output += "---------------\n\n"
                
#                 new_auto = await add_autoinfo(
#                     ad_id=info.get('id'),
#                     name=info.get('name'),
#                     year=info.get('year') or 0,
#                     usd_price=float(info.get('price_usd')),
#                     publish_time=info.get('publish_time'),
#                     all_phones=all_phones,
#                     link=info.get('link'),
#                     spam=False  # Можно передать True, если нужно отметить как spam
#                 )
#             except:
#                 pass
        
#     except Exception as e:
#         await call.message.answer(f"Ошибка при выполнении запроса: {e}")
#         return