import logging
import re
import sqlite3
import aiosqlite
from typing import Optional
from common.starrocks_connection import get_db_connection
from common.sqlite_db import sqlite_db
from common.constants import SQLITE_DB_PATH

logger = logging.getLogger(__name__)

def translate_query(query: str) -> str:
    """
    Dịch câu SQL đặc thù của StarRocks sang dạng mà SQLite hiểu được.
    Mượn logic từ sqlite_mock.py của bro.
    """
    # 1. Thay thế Placeholder (%s -> ?)
    q = re.sub(r'(?<!%)%s(?!%)', '?', query)

    # 2. Thay thế cấu trúc của StarRocks (table name)
    # test_db.magento_... → sr__test_db__magento_...
    q = re.sub(
        r'(?:test_db\.)?`?magento_product_dimension_with_text_embedding`?',
        r'sr__test_db__magento_product_dimension_with_text_embedding',
        q
    )

    # 3. Vá các ngữ pháp (Dialect)
    q = re.sub(r'ANY_VALUE\s*\(', r'MAX(', q, flags=re.IGNORECASE)
    q = re.sub(r'\bIF\s*\(', r'IIF(', q, flags=re.IGNORECASE)
    q = re.sub(r'NULLS\s+LAST', '', q, flags=re.IGNORECASE)
    q = re.sub(r'\bILIKE\b', 'LIKE', q, flags=re.IGNORECASE)
    q = re.sub(r'\bTRUE\b', '1', q, flags=re.IGNORECASE)
    q = re.sub(r'\bFALSE\b', '0', q, flags=re.IGNORECASE)

    # 4. FIND_IN_SET(%s, REPLACE(col, '|', ',')) > 0  → INSTR fallback
    # SQLite không hỗ trợ FIND_IN_SET, thay bằng INSTR
    q = re.sub(
        r"FIND_IN_SET\s*\(\s*(\?)\s*,\s*REPLACE\s*\(\s*(\w+)\s*,\s*'[|]'\s*,\s*','\s*\)\s*\)\s*>\s*0",
        r"('|' || \2 || '|') LIKE ('%|' || \1 || '|%')",
        q, flags=re.IGNORECASE
    )

    logger.debug(f"📝 [SQLite Translated] {q[:200]}")
    return q


class DBConnector:
    """
    Bộ điều phối DB: StarRocks vs SQLite.
    """
    def __init__(self, use_sqlite: bool = False):
        self.use_sqlite = use_sqlite

    async def execute_query(self, query: str, params: tuple = ()) -> list[dict]:
        if self.use_sqlite:
            t_query = translate_query(query)
            logger.info(f"📁 [DBConnector] Using SQLite Mock | Query: {t_query[:100]}...")
            try:
                return await sqlite_db.fetch_all(t_query, params)
            except Exception as e:
                logger.error(f"❌ [DBConnector] SQLite Error: {e}")
                return []
        else:
            logger.info(f"🚀 [DBConnector] Using StarRocks Production")
            db = get_db_connection()
            if not db:
                logger.error("❌ [DBConnector] StarRocks Connection Failed!")
                return []
            try:
                return await db.execute_query_async(query, params)
            except Exception as e:
                logger.error(f"❌ [DBConnector] StarRocks Error: {e}. Falling back to SQLite...")
                # Tự động cứu bồ
                t_query = translate_query(query)
                return await sqlite_db.fetch_all(t_query, params)
