<?php

namespace Planaday\Platform\WordpressConfig;

use mysqli_stmt;
use Planaday\Database\SQLDatabaseControllers\Table;
use Planaday\Platform\PlatformAbstraction\DatabaseInterface;
use Planaday\Utility\Debug\Log\Logging;
use Planaday\Utility\PluginData;

class WPDatabaseInterface implements DatabaseInterface {
	use Logging;
	public function __construct(
		protected PluginData $pluginData
	) {}

	/**
	 * @param Table $table
	 * @param string $queryString
	 *  use {pad-table} for the table, this will get replaced with the correct table string
	 * @param array $data
	 *
	 * @return null|array
	 */
	public function getQueryResults(Table $table, string $queryString, array $data = []): ?array {
		global $wpdb;

		$wpTable = $this->convertTableString($table->getName());

		$queryWithoutData = str_replace('{pad-table}', $wpTable, $queryString);

		$query = $wpdb->prepare($queryWithoutData, $data);

		return $this->sendQuery($query);
	}

	public function sendQuery(string $queryString): ?array {
		global $wpdb;

		$this->logDebug("sending query: $queryString");

		return $wpdb->get_results($queryString, ARRAY_A);
	}

	public function getLastGeneratedInsertId(): int {
		global $wpdb;
		return $wpdb->insert_id;
	}

	/**
	 * @param Table $table
	 * @param int|string $id
	 *
	 * @return bool
	 */
	public function idExists(Table $table, $id): bool{
		global $wpdb;

		$wpTable = $this->convertTableString($table->getName());

		$query = "SELECT COUNT(1) AS match_count FROM " . $wpTable . " WHERE id=%s";

		$this->logDebug("sending query: $query");

		$result = $wpdb->get_results($wpdb->prepare($query, array($id)));

		return $result[0]->match_count > 0;
	}

	public function getColumnsTable(Table $table): array {
		global $wpdb;

		$wpTable = $this->convertTableString($table->getName());

		$query = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='" . $wpTable . "'";

		$this->logDebug("sending query: $query");

		$columnInfo = $wpdb->get_results($query, ARRAY_A);

		$columns = [];

		foreach ($columnInfo as $resultRow){
			$columns[$resultRow['COLUMN_NAME']] = true;
		}

		return $columns;
	}

	public function convertTableString(string $tableName): string {
		global $wpdb;
		return $wpdb->prefix . str_replace('-','_', $this->pluginData->getShortPrefix()) . '_' . $tableName;
	}

	public function escapeSql( $input ): array|string {
		return esc_sql( $input );
	}

	/** @var array<string, mysqli_stmt> */
	protected array $preparedQueries = [];
	public function runPreparedQuery(string $query, array $data = []): false|array{
		if (!isset($this->preparedQueries[$query])){
			global $wpdb;
			$dbhost = $wpdb->dbh;

			if (!$dbhost) {
				$this->logError("dbhost is null");
				return false;
			}

			$statement = $dbhost->prepare($query . ';');
			if (!$statement) {
				$this->logError("Failed to prepare query: $query");
				$this->logError($dbhost->error);
				return false;
			}

			$this->preparedQueries[$query] = $statement;
		}

		$statement = $this->preparedQueries[$query];

		$this->logDebug("running prepared query: $query", $data);

		$typeString = '';
		foreach ($data as $value){
			if (is_int($value) || is_float($value)){
				$typeString .= 'd';
			} else {
				$typeString .= 's';
			}
		}

		$statement->bind_param($typeString, ...array_values($data));
		$statement->execute();
		return $data;
	}
}