<?php

namespace AcademyProCalendar\Events;

use Academy\Classes\AbstractAjaxHandler;
use Academy\Classes\Sanitizer;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

abstract class QueryAbstract {

	public ?string $query = null;
	public string $select;
	public string $count_col;
	public string $table;
	public string $join;
	public array $where;
	public array $args;
	public string $after_query    = '';
	public int $per_page       = 20;
	public int $current_page   = 1;
	public ?string $order_by       = null;
	public string $order_direction = 'DESC';

	public function get_events_data() : array {
		global $wpdb;
		$query = "SELECT {$this->select} FROM {$this->table} {$this->join} ";
		$count_query = "SELECT COUNT({$this->count_col}) FROM {$this->table} {$this->join} ";

		if ( ! empty( $this->where ) ) {
			$query .= ' WHERE ' . implode( ' AND ', $this->where );
			$count_query .= ' WHERE ' . implode( ' AND ', $this->where );
		}

		if ( empty( $this->args ) && empty( $this->where ) ) {
			$total = $wpdb->get_var( $count_query );// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		} else {
			$total = intval( $wpdb->get_var( $wpdb->prepare( $count_query, ...$this->args ) ) );// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		}

		if ( ! empty( $this->after_query ) ) {
			$query .= ' ' . $this->after_query;
		}

		// get a single row
		if ( 1 === $this->per_page ) {
			// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			return $wpdb->get_row( $wpdb->prepare( $query, ...$this->args ), ARRAY_A ) ?? [];
		}

		// order by
		if ( empty( $this->order_by ) ) {
			$this->order_by = 'ID';
		}
		// order direction
		if (
			! in_array( strtoupper( $this->order_direction ), [ 'ASC', 'DESC' ] )
		) {
			$this->order_direction = 'ASC';
		}
		$query .= " ORDER BY {$this->order_by} {$this->order_direction}";

		// get all data
		if ( 0 === $this->per_page ) {
			$this->query = $wpdb->prepare( $query, ...$this->args );// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			return [
				'total' => $total,
				'data' => $wpdb->get_results( $this->query, ARRAY_A ) ?? [], // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
			];
		}

		// pagination
		$this->current_page = absint( $this->current_page );
		$this->per_page = absint( $this->per_page );
		if ( $this->current_page < 1 || $this->current_page > $total ) {
			$this->current_page = 1;
		}
		if ( $this->per_page < 1 ) {
			$this->per_page = 20;
		}
		$offset = ( $this->current_page - 1 ) * $this->per_page;

		$query .= ' LIMIT %d OFFSET %d';
		$this->args[] = $this->per_page;
		$this->args[] = $offset;
		$this->query = $wpdb->prepare( $query, ...$this->args );// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return [
			'current_page' => $this->current_page,
			'total_pages'  => ( $this->per_page > 0 && $total > 0 ) ? ceil( $total / $this->per_page ) : 1,
			'per_page'     => $this->per_page,
			'total'        => $total,
			'data'         => $wpdb->get_results( $this->query, ARRAY_A ) ?? [], // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		];

	}
}
