import sqlite3
import logging
import json
import os

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

DATA_DB = 'data.db'
MENU_DB = 'bot_menu.db'
REFERAL_LINK_FILE = 'referal_link.json'

def get_bot_link() -> str:
    """
    Получает ссылку на бота из JSON файла
    """
    try:
        if os.path.exists(REFERAL_LINK_FILE):
            with open(REFERAL_LINK_FILE, 'r', encoding='utf-8') as f:
                data = json.load(f)
                return data.get('bot_link', 'https://t.me/asdasdass2dasdabot')
        else:
            # Создаем файл с дефолтным значением если его нет
            default_data = {"bot_link": "https://t.me/asdasdass2dasdabot"}
            with open(REFERAL_LINK_FILE, 'w', encoding='utf-8') as f:
                json.dump(default_data, f, ensure_ascii=False, indent=4)
            return "https://t.me/asdasdass2dasdabot"
    except Exception as e:
        logger.error(f"Error reading bot link from {REFERAL_LINK_FILE}: {e}")
        return "https://t.me/asdasdass2dasdabot"

def create_db():
    try:
        conn_data = sqlite3.connect(DATA_DB)
        cur = conn_data.cursor()
        
        # Таблица users
        cur.execute('''
            CREATE TABLE IF NOT EXISTS users (
                user_id INTEGER PRIMARY KEY,
                first_name TEXT,
                last_name TEXT,
                username TEXT,
                referal INTEGER DEFAULT 0,
                referal_balance REAL DEFAULT 0,
                referal_link TEXT,
                balance REAL DEFAULT 0,
                orders INTEGER DEFAULT 0,
                user_status BOOLEAN DEFAULT TRUE,
                user_language TEXT
            )
        ''')
        
        # Таблица referals - создаем только если не существует
        cur.execute('''
            CREATE TABLE IF NOT EXISTS referals (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                referals_user_id INTEGER,
                gen_referal_user_id INTEGER,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
                UNIQUE(referals_user_id, gen_referal_user_id)
            )
        ''')
        
        conn_data.commit()
        
        # Проверяем и добавляем колонки если нужно
        cur.execute("PRAGMA table_info(users)")
        cols = [r[1] for r in cur.fetchall()]
        if 'user_language' not in cols:
            cur.execute("ALTER TABLE users ADD COLUMN user_language TEXT")
            conn_data.commit()
            
        conn_data.close()
    except Exception as e:
        logger.error(f"Ошибка при создании data.db: {e}")

    try:
        conn_menu = sqlite3.connect(MENU_DB)
        curm = conn_menu.cursor()
        curm.execute('''
            CREATE TABLE IF NOT EXISTS language (
                name TEXT PRIMARY KEY,
                button1 TEXT, button2 TEXT, button3 TEXT, button4 TEXT, button5 TEXT,
                button6 TEXT, button7 TEXT, button8 TEXT, button9 TEXT, button10 TEXT,
                button11 TEXT, button12 TEXT, button13 TEXT, button14 TEXT, button15 TEXT,
                button16 TEXT, button17 TEXT, button18 TEXT, button19 TEXT, button20 TEXT,
                button21 TEXT, button22 TEXT,
                text1 TEXT, text2 TEXT, text3 TEXT, text4 TEXT, text5 TEXT,
                text6 TEXT, text7 TEXT, text8 TEXT, text9 TEXT, text10 TEXT,
                text11 TEXT, text12 TEXT, text13 TEXT, text14 TEXT, text15 TEXT,
                text16 TEXT, text17 TEXT, text18 TEXT, text19 TEXT, text20 TEXT,
                text21 TEXT, text22 TEXT, text23 TEXT, text24 TEXT, text25 TEXT, 
                text26 TEXT, text27 TEXT, text28 TEXT, text29 TEXT, text30 TEXT,
                text31 TEXT, text32 TEXT, text33 TEXT, text34 TEXT, text35 TEXT,
                text36 TEXT, text37 TEXT, text38 TEXT, text39 TEXT, text40 TEXT
            )
        ''')
        conn_menu.commit()
        conn_menu.close()
    except Exception as e:
        logger.error(f"Ошибка при создании bot_menu.db: {e}")


def add_user(user_id, first_name, last_name, username):
    try:
        conn = sqlite3.connect(DATA_DB)
        cur = conn.cursor()
        cur.execute('SELECT user_id FROM users WHERE user_id = ?', (user_id,))
        if cur.fetchone():
            conn.close()
            return
        
        # Получаем ссылку на бота из JSON файла
        bot_link = get_bot_link()
        referal_link = f"{bot_link}?start={user_id}"
        
        cur.execute('''
            INSERT INTO users (user_id, first_name, last_name, username, referal_link)
            VALUES (?, ?, ?, ?, ?)
        ''', (user_id, first_name, last_name, username, referal_link))
        conn.commit()
        conn.close()
    except Exception as e:
        logger.error(f"Ошибка при добавлении пользователя {user_id}: {e}")


def get_user_balance(user_id: int) -> float:
    try:
        conn = sqlite3.connect(DATA_DB)
        cur = conn.cursor()
        cur.execute("SELECT balance FROM users WHERE user_id = ?", (user_id,))
        row = cur.fetchone()
        conn.close()
        if row and row[0] is not None:
            try:
                return float(row[0])
            except Exception:
                return 0.0
    except Exception as e:
        logger.error(f"get_user_balance error user_id={user_id}: {e}")
        return 0.0


def update_user_balance(user_id: int, amount: float) -> bool:
    """
    Обновляет баланс пользователя (списание средств)
    """
    try:
        conn = sqlite3.connect(DATA_DB)
        cur = conn.cursor()
        cur.execute("UPDATE users SET balance = balance - ? WHERE user_id = ?", (amount, user_id))
        conn.commit()
        conn.close()
        return True
    except Exception as e:
        logger.error(f"update_user_balance error user_id={user_id}: {e}")
        return False


def add_user_balance(user_id: int, amount: float) -> bool:
    """
    Пополняет баланс пользователя
    """
    try:
        conn = sqlite3.connect(DATA_DB)
        cur = conn.cursor()
        cur.execute("UPDATE users SET balance = balance + ? WHERE user_id = ?", (amount, user_id))
        conn.commit()
        conn.close()
        logger.info(f"Balance added: user {user_id} +{amount}")
        return True
    except Exception as e:
        logger.error(f"add_user_balance error user_id={user_id}: {e}")
        return False


def handle_referal(referals_user_id: int, gen_referal_user_id: int) -> bool:
    """
    Обрабатывает реферальную регистрацию
    Returns: True если реферал успешно обработан, False если уже был обработан
    """
    try:
        conn = sqlite3.connect(DATA_DB)
        cur = conn.cursor()
        
        # Универсальная проверка - используем любую существующую колонку
        cur.execute("PRAGMA table_info(referals)")
        columns = [col[1] for col in cur.fetchall()]
        
        if not columns:
            # Если таблица пустая, создаем базовую запись
            check_query = "SELECT 1 FROM referals WHERE referals_user_id = ? AND gen_referal_user_id = ? LIMIT 1"
        else:
            # Используем первую доступную колонку для проверки
            check_column = columns[0]
            check_query = f"SELECT {check_column} FROM referals WHERE referals_user_id = ? AND gen_referal_user_id = ?"
        
        # Проверяем, не был ли уже этот реферал обработан
        cur.execute(check_query, (referals_user_id, gen_referal_user_id))
        if cur.fetchone():
            conn.close()
            print(f"Referal already processed: {referals_user_id} -> {gen_referal_user_id}")
            return False  # Уже был обработан
        
        # Добавляем запись в таблицу referals
        cur.execute(
            "INSERT INTO referals (referals_user_id, gen_referal_user_id) VALUES (?, ?)",
            (referals_user_id, gen_referal_user_id)
        )
        
        # Увеличиваем счетчик рефералов у пригласившего
        cur.execute(
            "UPDATE users SET referal = referal + 1 WHERE user_id = ?",
            (gen_referal_user_id,)
        )
        
        conn.commit()
        conn.close()
        
        print(f"Referal processed: user {referals_user_id} referred by {gen_referal_user_id}")
        return True
        
    except Exception as e:
        logger.error(f"Ошибка обработки реферала {referals_user_id} -> {gen_referal_user_id}: {e}")
        return False


def get_languages() -> list[str]:
    langs = []
    try:
        conn = sqlite3.connect(MENU_DB)
        cur = conn.cursor()
        cur.execute("SELECT name FROM language ORDER BY name COLLATE NOCASE")
        langs = [r[0] for r in cur.fetchall() if r and r[0]]
        conn.close()
    except Exception as e:
        logger.error(f"Ошибка при чтении языков: {e}")
    return langs


def get_user_language(user_id: int) -> str | None:
    try:
        conn = sqlite3.connect(DATA_DB)
        cur = conn.cursor()
        cur.execute("SELECT user_language FROM users WHERE user_id = ?", (user_id,))
        row = cur.fetchone()
        conn.close()
        return row[0] if row and row[0] else None
    except Exception as e:
        logger.error(f"Ошибка получения языка пользователя {user_id}: {e}")
        return None


def set_user_language(user_id: int, lang: str) -> bool:
    try:
        conn = sqlite3.connect(DATA_DB)
        cur = conn.cursor()
        cur.execute("UPDATE users SET user_language = ? WHERE user_id = ?", (lang, user_id))
        if cur.rowcount == 0:
            cur.execute("INSERT OR IGNORE INTO users (user_id, user_language) VALUES (?, ?)", (user_id, lang))
        conn.commit()
        conn.close()
        return True
    except Exception as e:
        logger.error(f"Ошибка сохранения языка для {user_id}: {e}")
        return False


def get_language_text(lang: str, field: str = "text1") -> str | None:
    """
    Получает текст для указанного поля и языка
    Поддерживает text1-text40 и button1-button22
    """
    if not lang:
        return None
    
    # Проверяем допустимые поля
    allowed_text_fields = {f"text{i}" for i in range(1, 41)}
    allowed_button_fields = {f"button{i}" for i in range(1, 23)}  # Только до button22
    allowed_fields = allowed_text_fields.union(allowed_button_fields)
    
    if field not in allowed_fields:
        logger.warning(f"Поле {field} не поддерживается, используется text1")
        field = "text1"
    
    try:
        conn = sqlite3.connect(MENU_DB)
        cur = conn.cursor()
        
        # Проверяем существует ли колонка в таблице
        cur.execute("PRAGMA table_info(language)")
        columns = [col[1] for col in cur.fetchall()]
        
        if field not in columns:
            logger.warning(f"Колонка {field} не существует в таблице language")
            conn.close()
            return None
        
        cur.execute(f"SELECT {field} FROM language WHERE name = ?", (lang,))
        row = cur.fetchone()
        conn.close()
        
        if row and row[0] is not None:
            text_value = str(row[0]).strip()
            if text_value:
                return text_value
        
        return None
        
    except Exception as e:
        logger.error(f"Ошибка чтения поля {field} для языка {lang}: {e}")
        return None


def get_language_buttons(lang: str) -> dict:
    """
    Возвращает словарь названий кнопок для языка:
    {'button1': '...', 'button2': '...', ..., 'button22': '...'}
    Пустые/NULL значения игнорируются при построении клавиатуры.
    """
    result = {}
    try:
        conn = sqlite3.connect(MENU_DB)
        cur = conn.cursor()
        
        # Получаем только существующие кнопки от button1 до button22
        fields = ",".join([f"button{i}" for i in range(1, 23)])  # Только до button22
        cur.execute(f"SELECT {fields} FROM language WHERE name = ?", (lang,))
        row = cur.fetchone()
        conn.close()
        
        if row:
            for i, val in enumerate(row, start=1):
                if val and str(val).strip():
                    result[f"button{i}"] = str(val).strip()
    except Exception as e:
        logger.error(f"Ошибка чтения кнопок для языка {lang}: {e}")
    return result


def get_button_text(lang: str, column: str, default_value: str = "") -> str:
    """
    Универсальный геттер текста кнопок по столбцу (button11, button12, button16 и т.д.)
    """
    # Проверяем допустимые поля кнопок (только до button22)
    allowed_button_fields = {f"button{i}" for i in range(1, 23)}
    
    if column not in allowed_button_fields:
        logger.warning(f"Кнопка {column} не поддерживается")
        return default_value
    
    try:
        conn = sqlite3.connect(MENU_DB)
        cur = conn.cursor()
        
        # Проверяем существует ли колонка в таблице
        cur.execute("PRAGMA table_info(language)")
        columns = [col[1] for col in cur.fetchall()]
        
        if column not in columns:
            logger.warning(f"Колонка {column} не существует в таблице language")
            conn.close()
            return default_value
        
        cur.execute(f"SELECT {column} FROM language WHERE name = ?", (lang,))
        row = cur.fetchone()
        conn.close()
        
        if row and row[0] and str(row[0]).strip():
            return str(row[0]).strip()
        else:
            return default_value
            
    except Exception as e:
        logger.error(f"get_button_text error col={column} lang={lang}: {e}")
        return default_value


def get_user_profile(user_id: int) -> dict:
    """
    Получает данные профиля пользователя из базы данных
    """
    try:
        conn = sqlite3.connect(DATA_DB)
        cursor = conn.cursor()
        
        cursor.execute('''
            SELECT user_id, username, first_name, balance, orders, referal 
            FROM users 
            WHERE user_id = ?
        ''', (user_id,))
        
        user_data = cursor.fetchone()
        conn.close()
        
        if user_data:
            return {
                'user_id': user_data[0],
                'username': user_data[1] or '',
                'first_name': user_data[2] or '',
                'balance': user_data[3] or 0,
                'orders': user_data[4] or 0,
                'referals': user_data[5] or 0  # Обратите внимание: referal (без s)
            }
        else:
            # Если пользователь не найден, возвращаем данные по умолчанию
            return {
                'user_id': user_id,
                'username': '',
                'first_name': '',
                'balance': 0,
                'orders': 0,
                'referals': 0
            }
            
    except Exception as e:
        logger.error(f"Ошибка получения профиля пользователя {user_id}: {e}")
        # Возвращаем данные по умолчанию в случае ошибки
        return {
            'user_id': user_id,
            'username': '',
            'first_name': '',
            'balance': 0,
            'orders': 0,
            'referals': 0
        }