import xml.etree.ElementTree as ET
from .proxy import MapperProxy

class SqlSession:
    def __init__(self, db_type: str, db_url: str, mapper_paths: list, models_module):
        self.db_type = db_type
        self.models_module = models_module
        self.registered_namespaces = set()
        
        # 【核心逻辑】根据不同的 db_type 创建连接
        self.conn = self._create_connection(db_type, db_url)
        
        self.sql_registry = {}
        self._load_mappers(mapper_paths)

    def _create_connection(self, db_type: str, db_url: str):
        """数据库连接适配工厂"""
        if db_type == "sqlite":
            import sqlite3
            conn = sqlite3.connect(db_url)
            # 配置 sqlite 返回字典/Row 格式
            conn.row_factory = sqlite3.Row 
            return conn
            
        elif db_type == "postgresql":
            # 注意：使用 pg 需提前 pip install "psycopg[binary]"
            import psycopg
            from psycopg.rows import dict_row
            # 配置 psycopg3 返回字典格式
            conn = psycopg.connect(db_url, row_factory=dict_row)
            return conn
            
        elif db_type == "mysql":
            # 预留扩展：如需支持 MySQL
            # import pymysql
            # return pymysql.connect(db_url, cursorclass=pymysql.cursors.DictCursor)
            pass
            
        else:
            raise ValueError(f"当前框架暂不支持该数据库类型: {db_type}")

    # ... (_load_mappers, has_namespace, _map_result 方法保持完全不变) ...

    def select_one(self, statement_id: str, params: dict = None):
        statement = self.sql_registry.get(statement_id)
        cursor = self.conn.cursor()
        
        # 统一执行 API
        cursor.execute(statement["sql"], params or {})
        row = cursor.fetchone()
        
        # 兼容不同驱动返回的字典形式，统一转为标准 dict 再映射
        row_dict = dict(row) if row else None
        return self._map_result(row_dict, statement["result_type"])

    def select_list(self, statement_id: str, params: dict = None):
        statement = self.sql_registry.get(statement_id)
        cursor = self.conn.cursor()
        cursor.execute(statement["sql"], params or {})
        rows = cursor.fetchall()
        return [self._map_result(dict(row), statement["result_type"]) for row in rows]

    def execute_update(self, statement_id: str, params: dict = None):
        statement = self.sql_registry.get(statement_id)
        cursor = self.conn.cursor()
        cursor.execute(statement["sql"], params or {})
        self.conn.commit()
        # 注意：不同驱动获取最后插入ID的方式可能略有不同，
        # 在真实生产级框架中，这里也需要根据 db_type 进行差异化处理
        return getattr(cursor, 'lastrowid', 0)

    def close(self):
        self.conn.close()

    def get_mapper(self, dao_class):
        return MapperProxy(self, dao_class)