<?php
/**
 * WordPressLogRepository - MySQL implementation of LogRepositoryInterface for WordPress
 *
 * Provides WordPress-specific database operations using $wpdb global.
 */

namespace CloudXM\SDK\Queue;

use CloudXM\SDK\Support\HasLogger;

/**
 * WordPress-specific implementation of LogRepositoryInterface
 *
 * This class provides database operations for log records in WordPress context.
 * It handles WordPress database operations using the $wpdb global and WordPress
 * specific formatting for prepared statements.
 */
class WordPressLogRepository implements LogRepositoryInterface
{
    use HasLogger;

    /**
     * Insert a log record into the specified table
     */
    public function insert(string $table, array $data): bool
    {
        global $wpdb;

        $result = $wpdb->insert(
            $wpdb->prefix . $table,
            $data,
            $this->getFormatArray($data)
        );

        return $result !== false;
    }

    /**
     * Select a batch of log records for processing
     */
    public function selectBatch(string $table, int $limit, int $minId = 0): array
    {
        global $wpdb;

        $sql = $wpdb->prepare("
            SELECT id, ts_ns, level, message, context, correlation_id, attempts, created_at
            FROM {$wpdb->prefix}{$table}
            WHERE status = 'pending' AND attempts < 5 AND id > %d
            ORDER BY id ASC
            LIMIT %d
            FOR UPDATE
        ", $minId, $limit);

        $rows = $wpdb->get_results($sql, ARRAY_A);

        // Note: payload field is built by LogShipper now, not here

        return $rows ?: [];
    }

    /**
     * Update attempts counter for claimed records
     */
    public function updateAttempts(string $table, array $ids): bool
    {
        if (empty($ids)) {
            return true;
        }

        global $wpdb;

        $placeholders = str_repeat('%d,', count($ids) - 1) . '%d';

        $sql = $wpdb->prepare("
            UPDATE {$wpdb->prefix}{$table}
            SET attempts = attempts + 1, last_attempt = %s
            WHERE id IN ({$placeholders})
        ", array_merge([current_time('mysql')], $ids));

        $result = $wpdb->query($sql);

        return $result !== false;
    }

    /**
     * Delete multiple log records
     */
    public function delete(string $table, array $ids): bool
    {
        if (empty($ids)) {
            return true;
        }

        global $wpdb;

        $placeholders = str_repeat('%d,', count($ids) - 1) . '%d';

        $sql = $wpdb->prepare("
            DELETE FROM {$wpdb->prefix}{$table}
            WHERE id IN ({$placeholders})
        ", $ids);

        $result = $wpdb->query($sql);

        return $result !== false;
    }

    /**
     * Update attempts counter for failed records
     */
    public function bumpAttempts(string $table, array $ids): bool
    {
        if (empty($ids)) {
            return true;
        }

        global $wpdb;

        $placeholders = str_repeat('%d,', count($ids) - 1) . '%d';

        $sql = $wpdb->prepare("
            UPDATE {$wpdb->prefix}{$table}
            SET attempts = attempts + 1, last_attempt = %s, status = 'failed'
            WHERE id IN ({$placeholders})
        ", array_merge([current_time('mysql')], $ids));

        $result = $wpdb->query($sql);

        return $result !== false;
    }

    /**
     * Get statistics about log records
     */
    public function getStats(string $table): array
    {
        global $wpdb;

        $sql = "
            SELECT
                COUNT(*) as total,
                SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,
                SUM(CASE WHEN status = 'sent' THEN 1 ELSE 0 END) as sent,
                SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) as failed
            FROM {$wpdb->prefix}{$table}
        ";

        $stats = $wpdb->get_row($sql, ARRAY_A);

        return $stats ?: ['total' => 0, 'pending' => 0, 'sent' => 0, 'failed' => 0];
    }

    /**
     * Clear all records from table
     */
    public function clearAll(string $table): bool
    {
        global $wpdb;

        $result = $wpdb->query("DELETE FROM {$wpdb->prefix}{$table}");

        return $result !== false;
    }

    /**
     * Purge old records based on age (failed records older than maxAgeSeconds)
     */
    public function purgeOld(string $table, int $maxAgeSeconds): int
    {
        global $wpdb;

        $sql = $wpdb->prepare("
            DELETE FROM {$wpdb->prefix}{$table}
            WHERE status = 'failed' AND attempts >= 5 AND last_attempt < %s
        ", date('Y-m-d H:i:s', time() - $maxAgeSeconds));

        $result = $wpdb->query($sql);

        return $result !== false ? $wpdb->rows_affected : 0;
    }

    /**
     * Generate format array for wpdb operations based on data types
     */
    private function getFormatArray(array $data): array
    {
        $formats = [];
        foreach ($data as $key => $value) {
            if (is_int($value) || is_float($value)) {
                $formats[] = '%d';
            } elseif (is_bool($value)) {
                $formats[] = '%d';
            } else {
                $formats[] = '%s';
            }
        }
        return $formats;
    }
}