import logging
import sqlite3

from pypos.core.utils.config_utils import read_config
from pypos.core.utils.db_helper import connect_sqlite
from pypos.core.utils.sql_identifier_utils import quote_sql_identifier

# edited by glg

LOGGER = logging.getLogger(__name__)


class TransactionExportDbService:
    def __init__(self, db_path, config_reader=read_config, connector=connect_sqlite):
        self.db_path = str(db_path or "")
        self.config_reader = config_reader
        self.connector = connector

    def quote_identifier(self, identifier: str) -> str:
        return quote_sql_identifier(identifier)

    def connect(self):
        conn = self.connector(self.db_path)
        try:
            config = self.config_reader() if callable(self.config_reader) else {}
            timeout_ms = int((config or {}).get("export_sqlite_busy_timeout_ms") or 0)
            if timeout_ms > 0:
                conn.execute(f"PRAGMA busy_timeout = {max(1, timeout_ms)}")
            if int((config or {}).get("export_sqlite_use_wal") or 0) == 1:
                conn.execute("PRAGMA journal_mode = WAL")
        except (TypeError, ValueError, sqlite3.Error) as exc:
            LOGGER.debug("[DEBUG EXPORT] pragma sqlite export diabaikan: %s", exc)
        conn.row_factory = sqlite3.Row
        return conn

    def table_exists(self, table_name: str) -> bool:
        conn = self.connect()
        try:
            cur = conn.cursor()
            cur.execute(
                "SELECT name FROM sqlite_master WHERE type='table' AND name = ?",
                (str(table_name or "").strip(),),
            )
            return cur.fetchone() is not None
        finally:
            conn.close()

    def ensure_column(self, cursor, table_name, col_name, col_type):
        table_sql = self.quote_identifier(table_name)
        col_sql = self.quote_identifier(col_name)
        col_type_sql = str(col_type or "").strip().upper()
        if col_type_sql not in {"TEXT", "INTEGER", "REAL", "BLOB", "NUMERIC"}:
            raise ValueError(f"Tipe kolom tidak valid: {col_type}")
        cursor.execute(f"PRAGMA table_info({table_sql})")
        cols = [row[1] for row in cursor.fetchall()]
        if col_name not in cols:
            cursor.execute(f"ALTER TABLE {table_sql} ADD COLUMN {col_sql} {col_type_sql}")
