import re
import logging
from contextlib import contextmanager

from .sqlite_db import sqlite_db

logger = logging.getLogger(__name__)

def translate_query(query: str) -> str:
    """
    Dịch câu SQL đặc thù của Postgres/StarRocks sang dạng mà SQLite hiểu được.
    """
    # 1. Thay thế Placeholder của Postgres/StarRocks (%s) thành của SQLite (?)
    q = query.replace("%s", "?")
    
    # 2. Thay thế Postgres Schema (dashboard_canifa)
    q = re.sub(r'"dashboard_canifa"\."([a-zA-Z0-9_]+)"', r'pg__dashboard_canifa__\1', q)
    q = re.sub(r'dashboard_canifa\.([a-zA-Z0-9_]+)', r'pg__dashboard_canifa__\1', q)
    
    # Thay thế Postgres Schema (canifa_chat)
    q = re.sub(r'"canifa_chat"\."([a-zA-Z0-9_]+)"', r'pg__canifa_chat__\1', q)
    q = re.sub(r'canifa_chat\.([a-zA-Z0-9_]+)', r'pg__canifa_chat__\1', q)
    
    # Thay thế Postgres Schema (public)
    q = re.sub(r'"public"\."([a-zA-Z0-9_]+)"', r'pg__public__\1', q)
    q = re.sub(r'public\.([a-zA-Z0-9_]+)', r'pg__public__\1', q)

    # 3. Thay thế cấu trúc của StarRocks
    # Mẫu query thường gặp: shared_source.magento_product_dimension_with_text_embedding
    # Hoặc test_db.magento_product_...
    # Hoặc magento_product_...
    q = re.sub(r'([a-zA-Z0-9_]+\.)?`?magento_product_dimension_with_text_embedding`?', r'sr__test_db__magento_product_dimension_with_text_embedding', q)
    
    # 4. Vá các ngữ pháp (Dialect) bị lệch pha
    # ANY_VALUE(col) -> MAX(col)
    q = re.sub(r'ANY_VALUE\s*\(', r'MAX(', q, flags=re.IGNORECASE)
    # IF(cond, true, false) -> IIF(cond, true, false) của SQLite
    # Lưu ý: Tìm chữ IF đứng đầu cẩn thận dính chuỗi
    q = re.sub(r'\bIF\s*\(', r'IIF(', q, flags=re.IGNORECASE)
    
    return q

class MockCursor:
    """
    Giả mạo con trỏ (Cursor) của thư viện psycopg / pymysql.
    """
    def __init__(self):
        self._last_results = []
        self._last_result = None
        self.rowcount = 0
        
    def execute(self, query: str, params: tuple = None):
        if params is None:
            params = ()
        tq = translate_query(query)
        logger.debug(f"[SQLITE MOCK] Đã biên dịch Query: {tq[:100]}...")
        
        is_select = tq.strip().lower().startswith("select")
        
        if is_select:
            self._last_results = sqlite_db.fetch_all(tq, params)
            self.rowcount = len(self._last_results)
        else:
            self.rowcount = sqlite_db.execute(tq, params)
            self._last_results = []
            
    def fetchall(self):
        return self._last_results
        
    def fetchone(self):
        if self._last_results:
            return self._last_results[0]
        return None

    # Hỗ trợ Async context manager cho một số hàm dùng `async with cursor()`
    async def __aenter__(self):
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        pass

    # Context manager đồng bộ (`with cursor()`)
    def __enter__(self):
        return self
        
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

class MockConnection:
    """
    Giả mạo kết nối DB của psycopg pool.
    """
    @contextmanager
    def cursor(self):
        """Mô phỏng `with conn.cursor() as cur:`"""
        yield MockCursor()
        
    def transaction(self):
        """Mô phỏng transaction (Fake block)"""
        @contextmanager
        def dummy_transaction():
            yield self
        return dummy_transaction()

@contextmanager
def get_mock_pg_conn():
    """
    Mô phỏng kết quả trả về của db_pool.get_conn()
    """
    logger.info("🛡️ [SQLITE MOCK] Đã đánh chặn PostgreSQL Connection -> Chạy truy vấn trên Local SQLite!")
    yield MockConnection()
