<?php

declare(strict_types=1);

namespace SeoScope\Repositories;

use PDO;

/**
 * Persisted payloads for deferred / expensive dashboard slices.
 *
 * **Consumers:** deferred widget blobs (`group_key` e.g. `trend`, `traffic`) and
 * POST `/dashboard/seo-ai-assistant` structured responses (opaque 32-char `group_key`;
 * JSON namespaced via {@see \SeoScope\Services\SeoAiAssistantDashboardCacheEnvelope}).
 */
final class DashboardCacheRepository
{
    public function __construct(
        private PDO $pdo,
        private string $tablePrefix
    ) {}

    private function table(): string
    {
        return '`' . str_replace('`', '``', $this->tablePrefix . 'dashboard_cache') . '`';
    }

    public function getPayload(int $userId, int $propertyId, string $preset, string $groupKey, string $computedForEnd): ?array
    {
        if ($userId < 1 || $propertyId < 1) {
            return null;
        }
        $preset = trim($preset);
        $groupKey = trim($groupKey);
        if ($preset === '' || $groupKey === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $computedForEnd)) {
            return null;
        }

        $t = $this->table();
        $stmt = $this->pdo->prepare(
            "SELECT payload_json, computed_at
             FROM {$t}
             WHERE user_id = ? AND property_id = ? AND preset = ? AND group_key = ? AND computed_for_end = ?
             LIMIT 1"
        );
        $stmt->execute([$userId, $propertyId, $preset, $groupKey, $computedForEnd]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!is_array($row)) {
            return null;
        }
        $raw = (string) ($row['payload_json'] ?? '');
        $payload = $raw !== '' ? json_decode($raw, true) : null;
        if (!is_array($payload)) {
            return null;
        }
        $payload['_computed_at'] = (string) ($row['computed_at'] ?? '');
        return $payload;
    }

    public function putPayload(int $userId, int $propertyId, string $preset, string $groupKey, string $computedForEnd, array $payload): void
    {
        if ($userId < 1 || $propertyId < 1) {
            return;
        }
        $preset = trim($preset);
        $groupKey = trim($groupKey);
        if ($preset === '' || $groupKey === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $computedForEnd)) {
            return;
        }

        $t = $this->table();
        $now = date('Y-m-d H:i:s');
        $json = json_encode($payload, JSON_UNESCAPED_SLASHES);
        if (!is_string($json)) {
            return;
        }

        // MySQL upsert.
        $stmt = $this->pdo->prepare(
            "INSERT INTO {$t} (user_id, property_id, preset, group_key, computed_for_end, payload_json, computed_at)
             VALUES (?, ?, ?, ?, ?, ?, ?)
             ON DUPLICATE KEY UPDATE payload_json = VALUES(payload_json), computed_at = VALUES(computed_at)"
        );
        $stmt->execute([$userId, $propertyId, $preset, $groupKey, $computedForEnd, $json, $now]);
    }
}

