import sqlite3

class PhaseDBConnection:
    def __init__(self, db_file):
        # Connect to SQLite database file
        self.conn = sqlite3.connect(db_file)
        self.cursor = self.conn.cursor()

    # ---------- Raw SQL ----------
    def execute(self, sql, params=()):
        return self.cursor.execute(sql, params)

    def commit(self):
        self.conn.commit()

    def fetchall(self):
        return self.cursor.fetchall()

    def fetchone(self):
        return self.cursor.fetchone()

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

    # ---------- PhaseDB Custom Helpers ----------
    def create_table(self, table_name, columns):
        """
        Create table with columns.
        columns = list of tuples: (column_name, type, default_value)
        Example: [("name","TEXT","''"), ("coins","INTEGER",0)]
        """
        col_defs = []
        for col in columns:
            if len(col) == 2:
                col_defs.append(f"{col[0]} {col[1]}")
            elif len(col) == 3:
                col_defs.append(f"{col[0]} {col[1]} DEFAULT {col[2]}")
        sql = f"CREATE TABLE IF NOT EXISTS {table_name} ({', '.join(col_defs)})"
        self.execute(sql)
        self.commit()

    def insert(self, table_name, row):
        keys = ", ".join(row.keys())
        question_marks = ", ".join(["?"]*len(row))
        values = tuple(row.values())
        sql = f"INSERT INTO {table_name} ({keys}) VALUES ({question_marks})"
        self.execute(sql, values)
        self.commit()
        return self.cursor.lastrowid

    def select(self, table_name, where=None):
        sql = f"SELECT * FROM {table_name}"
        params = ()
        if where:
            sql += f" WHERE {where[0]}"
            params = where[1]
        self.execute(sql, params)
        return self.fetchall()

    def update(self, table_name, updates, where=None):
        set_clause = ", ".join([f"{k} = ?" for k in updates.keys()])
        params = tuple(updates.values())
        sql = f"UPDATE {table_name} SET {set_clause}"
        if where:
            sql += f" WHERE {where[0]}"
            params += tuple(where[1])
        self.execute(sql, params)
        self.commit()

    def delete(self, table_name, where=None):
        sql = f"DELETE FROM {table_name}"
        params = ()
        if where:
            sql += f" WHERE {where[0]}"
            params = where[1]
        self.execute(sql, params)
        self.commit()


def connect(db_file):
    """
    Connect to a PhaseDB database file.
    Returns a PhaseDBConnection object.
    """
    return PhaseDBConnection(db_file)