<?php

namespace Groundhogg\DB;

use Groundhogg\Email_Log_Item;
use function Groundhogg\Ymd_His;

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

class Email_Log extends DB {


	public function get_db_suffix() {
		return 'gh_email_log';
	}

	public function get_primary_key() {
		return 'ID';
	}

	public function get_db_version() {
		return '1.0';
	}

	public function get_object_type() {
		return 'log';
	}

	public function get_date_key() {
		return 'date_sent';
	}

	public function create_object( $object ) {
		return new Email_Log_Item( $object );
	}

	/**
	 * Maybe serialize the args...
	 *
	 * @param $args
	 *
	 * @return array
	 */
	protected function maybe_serialize( $args ) {
		return array_map( 'maybe_serialize', $args );
	}

	/**
	 * Maybe universalize
	 *
	 * @param $obj
	 */
	protected function maybe_unserialize( $obj ) {

		if ( ! is_object( $obj ) ) {
			return $obj;
		}

		// unserialize member vars
		$obj = array_map( 'maybe_unserialize', get_object_vars( $obj ) );

		// Cast back to object
		return (object) $obj;
	}

	/**
	 * Wrap for serialization.
	 *
	 * @param array $data
	 *
	 * @return int
	 */
	public function add( $data = array() ) {

		$data = $this->maybe_serialize( $data );

		return parent::add( $data ); // TODO: Change the autogenerated stub
	}

	/**
	 * Wrapper for update
	 *
	 * @param int   $row_id_or_where
	 * @param array $data
	 * @param array $where
	 *
	 * @return bool
	 */
	public function update( $row_id_or_where = 0, $data = [], $where = [] ) {

		$data = $this->maybe_serialize( $data );

		return parent::update( $row_id_or_where, $data, $where ); // TODO: Change the autogenerated stub
	}

	/**
	 * Wrapper for maybe unserialize
	 *
	 * @param $row_id
	 *
	 * @return object|void
	 */
	public function get( $row_id ) {
		$obj = parent::get( $row_id );

		return $this->maybe_unserialize( $obj );
	}

	/**
	 * Wrapper for maybe unserialize
	 *
	 * @param $column
	 * @param $row_id
	 *
	 * @return object
	 */
	public function get_by( $column, $row_id ) {
		$obj = parent::get_by( $column, $row_id );

		return $this->maybe_unserialize( $obj );
	}

	public function query( $data = [], $ORDER_BY = '', $from_cache = true ) {

		// Don't allow low level people to see sensitive email logs
		if ( ! is_super_admin() ) {
			$data['is_sensitive'] = 0;
		}

		return parent::query( $data, $ORDER_BY, $from_cache );
	}

	/**
	 * Wrapper to add maybe unserialize
	 *
	 * @param array $query_vars
	 * @param bool  $from_cache
	 *
	 * @return array[]|int|object[]
	 */
	public function advanced_query( $query_vars = [], $from_cache = true ) {
		$objs = parent::advanced_query( $query_vars, $from_cache ); // TODO: Change the autogenerated stub

		if ( is_array( $objs ) ) {
			$objs = array_map( [ $this, 'maybe_unserialize' ], $objs );
		}

		return $objs;
	}

	/**
	 * Get columns and formats
	 *
	 * @access  public
	 * @since   2.1
	 */
	public function get_columns() {
		return array(
			'ID'              => '%d',
			'msg_id'          => '%s',
			'recipients'      => '%s',
			'from_address'    => '%s',
			'subject'         => '%s',
			'content'         => '%s',
			'altbody'         => '%s',
			'headers'         => '%s',
			'message_type'    => '%s',
			'email_service'   => '%s',
			'error_code'      => '%s',
			'error_message'   => '%s',
			'status'          => '%s',
			'retries'         => '%d',
			'queued_event_id' => '%d',
			'is_sensitive'    => '%d',
			'date_sent'       => '%s',
		);
	}

	/**
	 * Get columns and formats
	 *
	 * @access  public
	 * @since   2.1
	 */
	public function get_column_defaults() {
		return array(
			'ID'              => 0,
			'msg_id'          => '',
			'recipients'      => '',
			'from_address'    => '',
			'subject'         => '',
			'content'         => '',
			'altbody'         => '',
			'headers'         => '',
			'message_type'    => '',
			'queued_event_id' => 0,
			'email_service'   => '',
			'error_code'      => '',
			'error_message'   => '',
			'status'          => 'sent',
			'retries'         => 0,
			'is_sensitive'    => 0,
			'date_sent'       => Ymd_His(),
		);
	}

	public function get_searchable_columns() {
		return [
			'recipients',
			'from_address',
			'subject',
			'content',
			'headers'
		];
	}

	protected function maybe_register_filters() {

		parent::maybe_register_filters();

		$this->query_filters->register( 'recipients', function ( $filter, $where ) {
			global $wpdb;
			$recipients = array_map( 'sanitize_email', $filter['recipients'] );
			$subWhere   = $where->subWhere();
			foreach ( $recipients as $recipient ) {
				$subWhere->like( 'recipients', '%' . $wpdb->esc_like( $recipient ) . '%' );
			}
		} );
	}

	public function create_table() {

		global $wpdb;

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

		$sql = "CREATE TABLE " . $this->table_name . " (
		ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
		msg_id varchar({$this->get_max_index_length()}) NOT NULL,
		recipients text NOT NULL,
		from_address text NOT NULL,
		subject mediumtext NOT NULL,
		headers mediumtext NOT NULL,
		content longtext NOT NULL,
		altbody longtext NOT NULL,
		message_type varchar(20) NOT NULL,
		email_service varchar(20) NOT NULL,
		status varchar(20) NOT NULL,
		error_code varchar(30) NOT NULL,
		error_message text NOT NULL,
		retries bigint(20) unsigned NOT NULL,
		is_sensitive tinyint(1) NOT NULL,
		queued_event_id bigint(20) unsigned NOT NULL,
		date_sent datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
		PRIMARY KEY (ID),
		KEY status (status),
		KEY date_sent (date_sent)
		) {$this->get_charset_collate()};";

		dbDelta( $sql );

		update_option( $this->table_name . '_db_version', $this->version );
	}
}
