<?php

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

class Pixelmole_Followup_Logger {
	const TABLE = 'pixelmole_followup_logs';

	/** @var Pixelmole_Followup_Plugin */
	private $plugin;

	/** @var bool|null */
	private $table_exists_cache = null;

	public function __construct( Pixelmole_Followup_Plugin $plugin ) {
		$this->plugin = $plugin;
	}

	public function maybe_create_table() {
		if ( $this->table_exists() ) {
			return;
		}

		self::create_table();
		$this->table_exists_cache = true;
	}

	public static function create_table() {
		global $wpdb;

		$table_name = self::get_table_name();
		if ( empty( $table_name ) ) {
			return;
		}

		require_once ABSPATH . 'wp-admin/includes/upgrade.php';

		$charset_collate = $wpdb->get_charset_collate();
		$sql             = "CREATE TABLE {$table_name} (
			id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
			email_type varchar(20) NOT NULL,
			recipient varchar(255) NOT NULL,
			subject text NOT NULL,
			order_id bigint(20) unsigned NOT NULL DEFAULT 0,
			sent_at datetime NOT NULL,
			PRIMARY KEY  (id),
			KEY email_type (email_type),
			KEY sent_at (sent_at)
		) {$charset_collate};";

		dbDelta( $sql );
	}

	public static function drop_table() {
		global $wpdb;

		$table_name = self::get_table_name();
		if ( empty( $table_name ) ) {
			return;
		}

		// Table name is not user input; esc_sql() for extra safety.
		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange -- need to drop plugin table on uninstall.
		$wpdb->query( 'DROP TABLE IF EXISTS `' . esc_sql( $table_name ) . '`' );
	}

	public function log_email( $type, $recipient, $subject, $order_id = 0 ) {
		if ( empty( $recipient ) || ! $this->table_exists() ) {
			return;
		}

		global $wpdb;
		$table_name = self::get_table_name();

		$wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$table_name,
			[
				'email_type' => sanitize_key( $type ),
				'recipient'  => sanitize_email( $recipient ),
				'subject'    => wp_strip_all_tags( (string) $subject ),
				'order_id'   => $order_id ? absint( $order_id ) : 0,
				'sent_at'    => current_time( 'mysql', true ),
			],
			[ '%s', '%s', '%s', '%d', '%s' ]
		);
	}

	public function get_logs( $paged = 1, $per_page = 20 ) {
		if ( ! $this->table_exists() ) {
			return [
				'items' => [],
				'total' => 0,
			];
		}

		global $wpdb;
		$table_name = self::get_table_name();
		$paged      = max( 1, absint( $paged ) );
		$per_page   = max( 1, absint( $per_page ) );
		$offset     = ( $paged - 1 ) * $per_page;

		$items = $wpdb->get_results( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->prepare(
				'SELECT id, email_type, recipient, subject, order_id, sent_at FROM `' . esc_sql( $table_name ) . '` ORDER BY sent_at DESC LIMIT %d OFFSET %d',
				$per_page,
				$offset
			),
			ARRAY_A
		);

		$total = (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->prepare(
				'SELECT COUNT(*) FROM `' . esc_sql( $table_name ) . '` WHERE 1 = %d',
				1
			)
		);

		return [
			'items' => $items,
			'total' => $total,
		];
	}

	public function get_followup_email_count() {
		if ( ! $this->table_exists() ) {
			return 0;
		}

		global $wpdb;
		$table_name = self::get_table_name();

		return (int) $wpdb->get_var( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching
			$wpdb->prepare(
				'SELECT COUNT(*) FROM `' . esc_sql( $table_name ) . '` WHERE email_type = %s',
				'followup'
			)
		);
	}

	public function table_exists() {
		if ( null !== $this->table_exists_cache ) {
			return (bool) $this->table_exists_cache;
		}

		global $wpdb;
		$table_name = self::get_table_name();
		if ( empty( $table_name ) ) {
			return false;
		}

		$like   = $wpdb->esc_like( $table_name );
		$result = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $like ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching

		$this->table_exists_cache = ( $result === $table_name );

		return (bool) $this->table_exists_cache;
	}

	private static function get_table_name() {
		global $wpdb;

		if ( empty( $wpdb->prefix ) ) {
			return '';
		}

		return $wpdb->prefix . self::TABLE;
	}
}
