<?php

namespace WPSN\Modules\SchemaValidator;

defined('ABSPATH') || exit;

final class SchemaScanRepository
{
    /** @var \wpdb */
    private $db;

    private string $table;

    public function __construct(?\wpdb $db = null)
    {
        global $wpdb;
        $this->db = $db ?: $wpdb;
        $this->table = $this->db->prefix . 'wpsn_schema_scans';
    }

    /**
     * @param array<string,mixed> $params
     */
    public function create(array $params = []): int
    {
        $now = current_time('mysql');

        $row = [
            'status' => 'running',
            'initiated_by' => get_current_user_id() ?: null,
            'params' => !empty($params) ? wp_json_encode($params) : null,
            'stats' => null,
            'started_at' => $now,
            'finished_at' => null,
        ];

        $ok = $this->db->insert($this->table, $row, ['%s', '%d', '%s', '%s', '%s', '%s']);
        if (!$ok) {
            return 0;
        }

        return (int) $this->db->insert_id;
    }

    /**
     * @param array<string,mixed> $stats
     */
    public function finish(int $scanId, array $stats, string $status = 'done'): void
    {
        if ($scanId <= 0) {
            return;
        }

        $this->db->update(
            $this->table,
            [
                'status' => $status,
                'stats' => wp_json_encode($stats),
                'finished_at' => current_time('mysql'),
            ],
            ['id' => $scanId],
            ['%s', '%s', '%s'],
            ['%d']
        );
    }

    /**
     * @param array<string,mixed> $stats
     */
    public function updateStats(int $scanId, array $stats): void
    {
        if ($scanId <= 0) {
            return;
        }

        $this->db->update(
            $this->table,
            ['stats' => wp_json_encode($stats)],
            ['id' => $scanId],
            ['%s'],
            ['%d']
        );
    }

    /**
     * @return array<string,mixed>|null
     */
    public function get(int $scanId): ?array
    {
        if ($scanId <= 0) {
            return null;
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $row = $this->db->get_row(
            $this->db->prepare("SELECT * FROM {$this->table} WHERE id = %d", $scanId),
            ARRAY_A
        );

        return is_array($row) ? $row : null;
    }

    /**
     * @return array<string,mixed>|null
     */
    public function latest(): ?array
    {
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $row = $this->db->get_row("SELECT * FROM {$this->table} ORDER BY id DESC LIMIT 1", ARRAY_A);
        return is_array($row) ? $row : null;
    }

    /**
     * @return array<int,array<string,mixed>>
     */
    public function list(int $limit = 10): array
    {
        $limit = max(1, min(50, (int) $limit));
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $rows = $this->db->get_results("SELECT * FROM {$this->table} ORDER BY id DESC LIMIT {$limit}", ARRAY_A);
        return is_array($rows) ? $rows : [];
    }

    public function clearAll(): void
    {
        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
        $this->db->query("TRUNCATE TABLE {$this->table}");
    }
}
