<?php
/**
 * Persistence for scan results.
 *
 * @package WPLens
 */

namespace WPLens\Scans;

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

// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
// phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
// phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter
//
// Justification: this file is a data-access layer. Table names are built
// from $wpdb->prefix . a static suffix, which is safe by construction; the linter
// cannot prove that. All user input flows through $wpdb->prepare() placeholders.


final class ScanRepository {

	private function table(): string {
		global $wpdb;
		return $wpdb->prefix . 'wplens_scans';
	}

	public function insert( array $data ): int {
		global $wpdb;

		$findings = isset( $data['findings'] ) ? wp_json_encode( $data['findings'] ) : '{}';

		$row = array(
			'post_id'     => absint( $data['post_id'] ),
			'scan_type'   => substr( (string) ( $data['scan_type'] ?? 'local' ), 0, 32 ),
			'ai_provider' => $data['ai_provider'] ? substr( (string) $data['ai_provider'], 0, 32 ) : null,
			'score'       => isset( $data['score'] ) && null !== $data['score'] ? max( 0, min( 100, (int) $data['score'] ) ) : null,
			'findings'    => $findings,
			'created_at'  => current_time( 'mysql', true ),
		);

		$ok = $wpdb->insert( $this->table(), $row );
		return false === $ok ? 0 : (int) $wpdb->insert_id;
	}

	public function recent( int $limit = 50 ): array {
		global $wpdb;
		$table = $this->table();
		$limit = max( 1, min( 200, $limit ) );

		$rows = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT id, post_id, scan_type, ai_provider, score, created_at FROM {$table} ORDER BY created_at DESC LIMIT %d",
				$limit
			),
			ARRAY_A
		);
		return is_array( $rows ) ? $rows : array();
	}

	public function for_post( int $post_id, int $limit = 20 ): array {
		global $wpdb;
		$table = $this->table();

		$rows = $wpdb->get_results(
			$wpdb->prepare(
				"SELECT id, scan_type, ai_provider, score, findings, created_at FROM {$table} WHERE post_id = %d ORDER BY created_at DESC LIMIT %d",
				$post_id,
				$limit
			),
			ARRAY_A
		);
		return is_array( $rows ) ? $rows : array();
	}

	public function latest_for_post( int $post_id ): ?array {
		$rows = $this->for_post( $post_id, 1 );
		return $rows[0] ?? null;
	}

	public function find( int $id ): ?array {
		global $wpdb;
		$table = $this->table();

		$row = $wpdb->get_row(
			$wpdb->prepare( "SELECT * FROM {$table} WHERE id = %d", $id ),
			ARRAY_A
		);
		return $row ? $row : null;
	}
}
