<?php
namespace EasyChat\Model;

class Setting extends Base {

    public const REVISION_KEY = 'chat_settings_revision';

    public function get($key, $default = '') {
        $query = $this->db->query("SELECT `value` FROM `{$this->prefix}settings` WHERE `key` = '" . $this->db->escape($key) . "' LIMIT 1");
        if ($query->num_rows) {
            return $query->row['value'];
        }
        return $default;
    }

    public function getAll() {
        $query = $this->db->query("SELECT * FROM `{$this->prefix}settings`");
        $settings = [];
        foreach ($query->rows as $row) {
            $settings[$row['key']] = $row['value'];
        }
        return $settings;
    }

    public function set($key, $value) {
        $this->db->query("INSERT INTO `{$this->prefix}settings` (`key`, `value`) 
            VALUES ('" . $this->db->escape($key) . "', '" . $this->db->escape($value) . "') 
            ON DUPLICATE KEY UPDATE `value` = '" . $this->db->escape($value) . "'");
    }

    public function setMany($data) {
        foreach ($data as $key => $value) {
            $this->set($key, $value);
        }
    }

    






    public function setManyAtomic(array $data, ?callable $before_commit = null): void {
        $this->db->query('START TRANSACTION');
        try {
            $this->setMany($data);
            if ($before_commit !== null) {
                $before_commit();
            }
            $this->db->query('COMMIT');
        } catch (\Throwable $e) {
            try {
                $this->db->query('ROLLBACK');
            } catch (\Throwable $rollback_error) {
                 
                 
            }
            throw $e;
        }
    }

    





    public function compareAndSetMany(int $expected_revision, array $data, ?callable $before_commit = null): array {
        $expected_revision = max(0, $expected_revision);
        $this->db->query('START TRANSACTION');
        try {
            $this->db->query(
                "INSERT INTO `{$this->prefix}settings` (`key`, `value`)
                 VALUES ('" . self::REVISION_KEY . "', '0')
                 ON DUPLICATE KEY UPDATE `value` = `value`"
            );
            $revision_query = $this->db->query(
                "SELECT `value` FROM `{$this->prefix}settings`
                 WHERE `key` = '" . self::REVISION_KEY . "' LIMIT 1 FOR UPDATE"
            );
            $current_revision = max(0, (int)($revision_query->row['value'] ?? 0));
            if ($current_revision !== $expected_revision) {
                $this->db->query('ROLLBACK');
                return array(
                    'success' => false,
                    'revision' => $current_revision,
                    'current_revision' => $current_revision,
                );
            }

            unset($data[self::REVISION_KEY]);
            $this->setMany($data);
            $next_revision = $current_revision + 1;
            $this->set(self::REVISION_KEY, (string)$next_revision);
            if ($before_commit !== null) {
                $before_commit($next_revision);
            }
            $this->db->query('COMMIT');
            return array(
                'success' => true,
                'revision' => $next_revision,
                'current_revision' => $next_revision,
            );
        } catch (\Throwable $e) {
            try {
                $this->db->query('ROLLBACK');
            } catch (\Throwable $rollback_error) {
                 
            }
            throw $e;
        }
    }
}
