<?php

namespace AC_SYNC\Includes\Classes\Sync;

if (!defined('ABSPATH'))
    exit;

/**
 * Persistent sync state storage.
 *
 * Replaces WordPress transients (which can expire and be lost)
 * with durable storage in actionwear_sync_state table.
 * Falls back to wp_options if the table doesn't exist yet.
 */
class Action_Wear_Sync_State
{
    /**
     * Get a state value for a process.
     *
     * @param string $processKey Process identifier (e.g., 'bulk_price_sync')
     * @param string $stateKey   State key (e.g., 'skus', 'chunk_dir')
     * @param mixed  $default    Default value if not found
     * @return mixed
     */
    public static function get($processKey, $stateKey, $default = false)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'actionwear_sync_state';

        if (self::tableExists()) {
            $value = $wpdb->get_var($wpdb->prepare(
                "SELECT state_value FROM $table WHERE process_key = %s AND state_key = %s",
                $processKey,
                $stateKey
            ));

            if ($value === null) {
                return $default;
            }

            $decoded = json_decode($value, true);
            return ($decoded !== null || $value === 'null') ? $decoded : $value;
        }

        // Fallback to wp_options
        $optionKey = '_aw_state_' . $processKey . '_' . $stateKey;
        return get_option($optionKey, $default);
    }

    /**
     * Set a state value for a process.
     *
     * @param string $processKey Process identifier
     * @param string $stateKey   State key
     * @param mixed  $value      Value to store (will be JSON-encoded)
     * @return bool
     */
    public static function set($processKey, $stateKey, $value)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'actionwear_sync_state';
        $encoded = json_encode($value);

        if (self::tableExists()) {
            $result = $wpdb->replace($table, [
                'process_key' => $processKey,
                'state_key' => $stateKey,
                'state_value' => $encoded,
            ], ['%s', '%s', '%s']);

            return $result !== false;
        }

        // Fallback to wp_options
        $optionKey = '_aw_state_' . $processKey . '_' . $stateKey;
        return update_option($optionKey, $value);
    }

    /**
     * Delete a state value for a process.
     *
     * @param string $processKey Process identifier
     * @param string $stateKey   State key
     * @return bool
     */
    public static function delete($processKey, $stateKey)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'actionwear_sync_state';

        if (self::tableExists()) {
            $result = $wpdb->delete($table, [
                'process_key' => $processKey,
                'state_key' => $stateKey,
            ], ['%s', '%s']);

            return $result !== false;
        }

        // Fallback to wp_options
        $optionKey = '_aw_state_' . $processKey . '_' . $stateKey;
        return delete_option($optionKey);
    }

    /**
     * Delete all state for a process (cleanup).
     *
     * @param string $processKey Process identifier
     * @return bool
     */
    public static function deleteAll($processKey)
    {
        global $wpdb;
        $table = $wpdb->prefix . 'actionwear_sync_state';

        if (self::tableExists()) {
            $result = $wpdb->delete($table, [
                'process_key' => $processKey,
            ], ['%s']);

            return $result !== false;
        }

        // Fallback: delete all matching wp_options
        $prefix = '_aw_state_' . $processKey . '_';
        $wpdb->query($wpdb->prepare(
            "DELETE FROM {$wpdb->options} WHERE option_name LIKE %s",
            $wpdb->esc_like($prefix) . '%'
        ));

        return true;
    }

    /**
     * Check if the sync state table exists.
     *
     * @return bool
     */
    private static function tableExists()
    {
        static $exists = null;
        if ($exists !== null) return $exists;

        global $wpdb;
        $table = $wpdb->prefix . 'actionwear_sync_state';
        $exists = $wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table)) === $table;
        return $exists;
    }
}
