import os
import json
import base64
import requests
import asyncio
import re

from dotenv import load_dotenv


load_dotenv()


def _get_turbosms_basic_token() -> str | None:
    """
    TurboSMS: заголовок Authorization: Basic <base64(login:password)>
    Данные — в кабинете TurboSMS, раздел подключения к шлюзу / HTTP API.

    В TOKEN_PHONE можно указать:
    - уже готовую base64-строку (как в документации, без префикса Basic);
    - или пару логин:пароль шлюзу в открытом виде — закодируем в base64 сами.
    """
    raw = (os.getenv("TOKEN_PHONE") or "").strip()
    if len(raw) >= 2 and ((raw[0] == raw[-1] == '"') or (raw[0] == raw[-1] == "'")):
        raw = raw[1:-1].strip()
    if not raw:
        return None
    if ":" in raw:
        return base64.b64encode(raw.encode("utf-8")).decode("ascii")
    return raw


TOKEN_PHONE = os.getenv("TOKEN_PHONE")  # для обратной совместимости; в запросах используйте _get_turbosms_basic_token()

numbres = [
    '380681244201'
]

def clean_phone_number(phone):
    """
    Очищает один номер и приводит к международному формату 380XXXXXXXXX.
    Мобильные UA только; стационарные / 0-800 отбрасываются.
    """
    if not phone:
        return None

    cleaned = re.sub(r"[^\d]", "", str(phone))
    if not cleaned:
        return None

    # Если номер начинается с 0, заменяем на 380
    if cleaned.startswith("0"):
        cleaned = "380" + cleaned[1:]
    elif cleaned.startswith("38"):
        pass
    elif len(cleaned) == 9:
        cleaned = "380" + cleaned
    else:
        return None

    if len(cleaned) != 12 or not cleaned.startswith("380"):
        return None

    # Только мобильные коды (не городские 0432… и не 0-800…)
    mobile_codes = {
        "39", "50", "63", "66", "67", "68", "73", "75",
        "91", "92", "93", "94", "95", "96", "97", "98", "99",
    }
    if cleaned[3:5] not in mobile_codes:
        return None

    return cleaned


def extract_clean_phones(raw) -> list:
    """
    Достаёт все валидные мобильные номера из строки/списка.
    Auto.RIA часто отдаёт несколько номеров одной строкой через запятую:
    '(067) 431-82-29, (093) 170-77-40, 0-800-21-00-12'
    """
    if raw is None:
        return []

    if isinstance(raw, (list, tuple, set)):
        out: list = []
        seen: set = set()
        for item in raw:
            for phone in extract_clean_phones(item):
                if phone not in seen:
                    seen.add(phone)
                    out.append(phone)
        return out

    text = str(raw).strip()
    if not text:
        return []

    chunks = re.split(r"[,;|/]+", text)
    # Если кусок всё ещё «слипшийся», дополнительно режем по границе ) (
    expanded: list = []
    for chunk in chunks:
        chunk = chunk.strip()
        if not chunk:
            continue
        parts = re.split(r"(?<=\))\s*(?=\()", chunk)
        expanded.extend(p.strip() for p in parts if p.strip())

    found: list = []
    seen: set = set()
    for chunk in expanded:
        cleaned = clean_phone_number(chunk)
        if cleaned and cleaned not in seen:
            seen.add(cleaned)
            found.append(cleaned)

    # Fallback: паттерны вида 0XX XXX-XX-XX / +380...
    if not found:
        for m in re.finditer(
            r"(?:\+?38)?0?\s*\(?\d{2,3}\)?[\s\-]*\d{2,3}[\s\-]*\d{2,3}[\s\-]*\d{2,4}",
            text,
        ):
            cleaned = clean_phone_number(m.group(0))
            if cleaned and cleaned not in seen:
                seen.add(cleaned)
                found.append(cleaned)

    return found

import logging

# Настройка логгера
logger = logging.getLogger(__name__)


def _turbosms_response_ok(data: object) -> tuple[bool, str | None]:
    """
    TurboSMS для корректного запроса всегда отдаёт HTTP 200.
    Реальный результат — в JSON: response_code 0 и обычно response_status OK.
    """
    if not isinstance(data, dict):
        return False, "Неверный JSON в ответе TurboSMS"
    rc = data.get("response_code")
    rs = data.get("response_status")
    # rc=0 — стандартный успех; rc=801 — SUCCESS_MESSAGE_SENT (принято к отправке)
    if rc == 0 or rc == 801:
        return True, None
    return False, f"{rs} (code {rc})"


async def send_sms(number: list) -> dict:
    """
    Отправляет SMS и возвращает результат операции
    Returns: {'success': bool, 'sent_count': int, 'failed_count': int, 'details': list}
    """
    logger.info(f"🔍 Отправка SMS на номера: {number}")
    
    # Валидация и очистка номеров
    valid_numbers = []
    for phone in number:
        cleaned = clean_phone_number(phone)
        if cleaned:
            valid_numbers.append(cleaned)
            logger.info(f"✅ Валидный номер: {phone} -> {cleaned}")
        else:
            logger.warning(f"❌ Невалидный номер: {phone}")
    
    if not valid_numbers:
        error_msg = "Нет валидных номеров для отправки SMS"
        logger.warning(f"❌ {error_msg}")
        return {
            'success': False,
            'sent_count': 0,
            'failed_count': len(number),
            'details': [],
            'error_message': error_msg
        }
    
    logger.info(f"📱 Отправляем SMS на {len(valid_numbers)} валидных номеров: {valid_numbers}")
    
    # Импортируем функцию получения настроек
    from app.database.crud_sms import get_sms_settings
    
    # Получаем настройки SMS из базы данных
    try:
        settings = await get_sms_settings()
        sms_text = settings.sms_text
        sender_name = settings.sender_name
        logger.info(f"📝 Используем текст: {sms_text}")
        logger.info(f"👤 Используем отправителя: {sender_name}")
    except Exception as e:
        # Fallback на дефолтные значения если что-то пошло не так
        sms_text = "TurboSMS приветствует Вас!"
        sender_name = "Buy_Auto"
        logger.warning(f"⚠️ Ошибка получения SMS настроек, используем дефолтные: {e}")
    
    api_url = "https://api.turbosms.ua/message/send.json"

    # Используем полученные настройки в payload
    payload = {
        "sender": sender_name,
        "recipients": valid_numbers,  # Используем очищенные номера
        "sms": {
            "sender": sender_name,
            "text": sms_text  # Используем текст из настроек!
        }
    }
    
    print(f"📦 Payload для отправки:")
    print(json.dumps(payload, indent=2, ensure_ascii=False))

    basic_secret = _get_turbosms_basic_token()
    if not basic_secret:
        error_msg = "TOKEN_PHONE не задан в .env (нужен base64(login:password) или логин:пароль шлюзу TurboSMS)"
        logger.error("❌ %s", error_msg)
        return {
            "success": False,
            "sent_count": 0,
            "failed_count": len(number),
            "details": [],
            "error_message": error_msg,
        }

    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Basic {basic_secret}",
    }

    result = {
        'success': False,
        'sent_count': 0,
        'failed_count': len(number),
        'details': [],
        'error_message': None
    }
    
    # Выполнение POST-запроса
    try:
        response = requests.post(api_url, headers=headers, json=payload)
        response.raise_for_status()
        
        print(f"HTTP Status: {response.status_code}")
        
        # Обработка ответа (TurboSMS: HTTP 200 даже при INVALID_TOKEN и др.)
        data = response.json()
        print("Ответ сервера:")
        print(json.dumps(data, indent=4, ensure_ascii=False))
        result["details"] = data

        if response.status_code != 200:
            result["error_message"] = f"HTTP {response.status_code}"
            print(f"❌ Ошибка HTTP: {response.status_code}")
        else:
            ok, err = _turbosms_response_ok(data)
            if ok:
                result["success"] = True
                result["sent_count"] = len(valid_numbers)
                result["failed_count"] = len(number) - len(valid_numbers)
                print(f"✅ SMS успешно отправлены на {len(valid_numbers)} номеров")
            else:
                result["success"] = False
                result["sent_count"] = 0
                result["failed_count"] = len(valid_numbers)
                result["error_message"] = f"TurboSMS: {err}"
                logger.error("❌ TurboSMS отказ: %s", err)
                if err and "INVALID_TOKEN" in str(err):
                    logger.error(
                        "Подсказка: сгенерируйте base64 в кабинете TurboSMS (HTTP API) или задайте "
                        "TOKEN_PHONE=ваш_логін:пароль_шлюзу — не путайте с паролем от сайта."
                    )
                print(f"❌ TurboSMS: {err}")
            
    except requests.exceptions.HTTPError as err:
        error_msg = f"Ошибка HTTP: {err}"
        print(error_msg)
        result['error_message'] = error_msg
    except Exception as err:
        error_msg = f"Ошибка запроса: {err}"
        print(error_msg)
        result['error_message'] = error_msg
    
    return result


# Оставляем старую синхронную версию для совместимости
def send_sms_sync(number: list) -> dict:
    """
    Синхронная версия отправки SMS с фиксированными настройками
    """
    api_url = "https://api.turbosms.ua/message/send.json"

    payload = {
        "sender": "Buy_Auto",
        "recipients": number, # телефон получателя в международном формате
        "sms": {
            "sender": "Buy_Auto",         # имя отправителя (зарегистрированное в системе)
            "text": "TurboSMS приветствует Вас!"
        }
    }
    basic_secret = _get_turbosms_basic_token()
    if not basic_secret:
        return {
            "success": False,
            "sent_count": 0,
            "failed_count": len(number),
            "details": [],
            "error_message": "TOKEN_PHONE не задан в .env",
        }
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Basic {basic_secret}",
    }

    result = {
        'success': False,
        'sent_count': 0,
        'failed_count': len(number),
        'details': [],
        'error_message': None
    }
    
    # Выполнение POST-запроса
    try:
        response = requests.post(api_url, headers=headers, json=payload)  # Исправлено: POST вместо GET
        response.raise_for_status()  # вызовет исключение для кодов ответа с ошибкой
        
        print(f"HTTP Status: {response.status_code}")
        
        data = response.json()
        print("Ответ сервера:")
        print(json.dumps(data, indent=4, ensure_ascii=False))
        result["details"] = data

        if response.status_code != 200:
            result["error_message"] = f"HTTP {response.status_code}"
        else:
            ok, err = _turbosms_response_ok(data)
            if ok:
                result["success"] = True
                result["sent_count"] = len(number)
                result["failed_count"] = 0
            else:
                result["success"] = False
                result["sent_count"] = 0
                result["failed_count"] = len(number)
                result["error_message"] = f"TurboSMS: {err}"
                logger.error("❌ TurboSMS отказ: %s", err)
            
    except requests.exceptions.HTTPError as err:
        error_msg = f"Ошибка HTTP: {err}"
        print(error_msg)
        result['error_message'] = error_msg
    except Exception as err:
        error_msg = f"Ошибка запроса: {err}"
        print(error_msg)
        result['error_message'] = error_msg
    
    return result


# send_sms(numbres)


# def chech_senders():
#     r = requests.get(
#         f"https://api.turbosms.ua/chat/senders.json",
#         headers = {
#             "Content-Type": "application/json",
#             "Authorization": f"Basic {TOKEN_PHONE}"
#         }
#     )
    
#     if r.status_code == 200:
#         print(r.text)
#     else:
#         print(r.status_code)


# chech_senders()
