import json
from collections.abc import MutableMapping

from db.database import conn, cursor


class JsonTableStore(MutableMapping):
    def __init__(self, table_name, key_column="user_id"):
        self.table_name = table_name
        self.key_column = key_column

    def __getitem__(self, key):
        cursor.execute(
            f"SELECT data_json FROM {self.table_name} WHERE {self.key_column} = ?",
            (int(key),)
        )
        row = cursor.fetchone()
        if not row:
            raise KeyError(key)
        return json.loads(row["data_json"])

    def __setitem__(self, key, value):
        cursor.execute(
            f"""
            INSERT INTO {self.table_name} ({self.key_column}, data_json)
            VALUES (?, ?)
            ON CONFLICT({self.key_column}) DO UPDATE SET
                data_json = excluded.data_json,
                updated_at = datetime('now', 'localtime')
            """,
            (int(key), json.dumps(value, ensure_ascii=False))
        )
        conn.commit()

    def __delitem__(self, key):
        cursor.execute(
            f"DELETE FROM {self.table_name} WHERE {self.key_column} = ?",
            (int(key),)
        )
        conn.commit()
        if cursor.rowcount == 0:
            raise KeyError(key)

    def __iter__(self):
        cursor.execute(
            f"SELECT {self.key_column} FROM {self.table_name} ORDER BY created_at"
        )
        for row in cursor.fetchall():
            yield row[self.key_column]

    def __len__(self):
        cursor.execute(f"SELECT COUNT(*) FROM {self.table_name}")
        return cursor.fetchone()[0]

    def __contains__(self, key):
        cursor.execute(
            f"SELECT 1 FROM {self.table_name} WHERE {self.key_column} = ?",
            (int(key),)
        )
        return cursor.fetchone() is not None
