<?php
/**
 * Caterpoint Cursor Store Service
 *
 * @category    PortalPeople
 * @package     Caterpoint
 * @author      Portal People Development Team
 * @copyright   Copyright (c) 2026 Portal People (https://portalpeople.co.uk)
 */

namespace PortalPeople\caterpoint\services;

use Yii;
use yii\base\BaseObject;
use yii\caching\CacheInterface;

/**
 * Cursor Store Service
 * 
 * Manages and persists the import cursor for tracking order synchronization progress
 */
class CaterpointCursorStore extends BaseObject
{
    /**
     * @var string Cache key for storing the cursor in the cache layer
     */
    public string $cacheKey = 'caterpoint.order-import.cursor';

    /**
     * @var string File path for persistent cursor storage
     * 
     * If set, the cursor will also be saved to this file as a fallback
     * for persistence across cache clears
     */
    public string $filePath = '';

    /**
     * @var CacheInterface Cache component to use
     */
    private ?CacheInterface $cache = null;

    /**
     * Initialize the cursor store
     */
    public function init(): void
    {
        parent::init();

        try {
            $this->cache = Yii::$app->cache;
        } catch (\Exception $e) {
            Yii::warning('Cache not available for cursor store: ' . $e->getMessage());
            $this->cache = null;
        }
    }

    /**
     * Get the current cursor value
     * 
     * Attempts to retrieve from cache first, then falls back to file storage
     * 
     * @return string|null Current cursor value or null if not set
     */
    public function get(): ?string
    {
        // Try cache first
        if ($this->cache !== null) {
            $cursor = $this->cache->get($this->cacheKey);
            if ($cursor !== false) {
                return (string) $cursor ?: null;
            }
        }

        // Fall back to file storage
        if (!empty($this->filePath) && file_exists($this->filePath)) {
            $content = file_get_contents($this->filePath);
            if ($content !== false) {
                $cursor = trim($content);
                return $cursor ?: null;
            }
        }

        return null;
    }

    /**
     * Set the cursor value
     * 
     * Stores in cache and optionally in file for persistence
     * 
     * @param string $cursor New cursor value
     * @return bool Success
     */
    public function set(string $cursor): bool
    {
        $success = true;

        // Store in cache
        if ($this->cache !== null) {
            $this->cache->set($this->cacheKey, $cursor);
        }

        // Store in file
        if (!empty($this->filePath)) {
            $dir = dirname($this->filePath);
            if (!is_dir($dir)) {
                @mkdir($dir, 0755, true);
            }

            if (@file_put_contents($this->filePath, $cursor) === false) {
                Yii::warning("Failed to write cursor to file: {$this->filePath}");
                $success = false;
            }
        }

        return $success;
    }

    /**
     * Clear the cursor value
     * 
     * @return bool Success
     */
    public function clear(): bool
    {
        $success = true;

        if ($this->cache !== null) {
            $this->cache->delete($this->cacheKey);
        }

        if (!empty($this->filePath) && file_exists($this->filePath)) {
            if (@unlink($this->filePath) === false) {
                Yii::warning("Failed to delete cursor file: {$this->filePath}");
                $success = false;
            }
        }

        return $success;
    }
}
