<?php
/**
 * Model: Email.php.
 *
 * @package RewardsWP
 */

namespace Awesomemotive\Rewardswp\Models;

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

use Awesomemotive\Rewardswp\Abstracts\AbstractModelWithMeta;
use Awesomemotive\Rewardswp\Database\DatabaseHandler;
use Awesomemotive\Rewardswp\Database\Tables\EmailsTable;
use Exception;
use function Awesomemotive\Rewardswp\Helpers\get_current_time;

/**
 * Class Email
 *
 * Represents the email entity and handles database interactions.
 *
 * @since 1.0.0
 */
class Email extends AbstractModelWithMeta {
	/**
	 * WordPress database handler.
	 *
	 * @since 1.0.0
	 * @var DatabaseHandler
	 */
	protected DatabaseHandler $db_handler;

	/**
	 * Table name.
	 *
	 * @since 1.0.0
	 * @var EmailsTable
	 */
	protected EmailsTable $db_table;

	/**
	 * Properties representing email fields.
	 *
	 * @since 1.0.0
	 * @var int
	 */
	public int $id = 0;

	/**
	 * Email unique identifier/name.
	 *
	 * @since 1.0.0
	 * @var string
	 */
	public string $name = '';

	/**
	 * Email subject (can contain placeholders).
	 *
	 * @since 1.0.0
	 * @var string
	 */
	public string $subject = '';

	/**
	 * Email context (Account, Referral, Points, Order).
	 *
	 * @since 1.0.0
	 * @var string
	 */
	public string $context = '';

	/**
	 * Recipient type (Customer, Admin, User).
	 *
	 * @since 1.0.0
	 * @var string
	 */
	public string $recipient_type = '';

	/**
	 * Email sender identifier.
	 *
	 * @since 1.0.0
	 * @var string
	 */
	public string $sender = 'RewardsWP Core';

	/**
	 * Whether the email is enabled.
	 *
	 * @since 1.0.0
	 * @var bool
	 */
	public bool $is_enabled = true;

	/**
	 * Date when the email was created.
	 *
	 * @since 1.0.0
	 * @var string
	 */
	public string $created_at = '';

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 *
	 * @param DatabaseHandler $db_handler The database handler.
	 * @param EmailsTable     $db_table   The emails table.
	 */
	public function __construct( DatabaseHandler $db_handler, EmailsTable $db_table ) {
		$this->db_handler = $db_handler;
		$this->db_table   = $db_table;
	}

	/**
	 * Validate the props from an object before creation.
	 *
	 * @since 1.0.0
	 *
	 * @return bool True if passes validation.
	 * @throws Exception If validation fails.
	 */
	public function validate_create(): bool {
		if ( empty( $this->name ) ) {
			throw new Exception( 'Email name is required.' );
		}

		if ( strlen( $this->name ) > 100 ) {
			throw new Exception( 'Email name cannot exceed 100 characters.' );
		}

		return true;
	}

	/**
	 * Validate the props from an object before updating.
	 *
	 * @since 1.0.0
	 *
	 * @return bool True if passes validation.
	 * @throws Exception If validation fails.
	 */
	public function validate_update(): bool {
		if ( empty( $this->id ) ) {
			throw new Exception( 'Cannot update email without an ID.' );
		}

		return $this->validate_create();
	}

	/**
	 * Sanitize the object props before saving.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function sanitize(): void {
		$this->name = sanitize_text_field( $this->name );
		// Allow single quotes and basic punctuation without being double-escaped.
		$this->subject        = wp_strip_all_tags( (string) $this->subject );
		$this->context        = sanitize_text_field( $this->context );
		$this->recipient_type = sanitize_text_field( $this->recipient_type );
		$this->sender         = sanitize_text_field( $this->sender );
	}

	/**
	 * Get labels for all email fields.
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	public function get_labels(): array {
		return [
			'id'             => __( 'ID', 'rewardswp' ),
			'name'           => __( 'Email Name', 'rewardswp' ),
			'subject'        => __( 'Subject', 'rewardswp' ),
			'context'        => __( 'Context', 'rewardswp' ),
			'recipient_type' => __( 'Recipient Type', 'rewardswp' ),
			'sender'         => __( 'Sender', 'rewardswp' ),
			'is_enabled'     => __( 'Enabled', 'rewardswp' ),
			'created_at'     => __( 'Created At', 'rewardswp' ),
		];
	}



	/**
	 * Get email by name.
	 *
	 * @since 1.0.0
	 *
	 * @param string $name The email name.
	 *
	 * @return ?array The email data or null if not found.
	 */
	public function get_by_name( string $name ): ?array {
		return $this->db_handler->get_row(
			$this->db_table->get_prefixed_table_name(),
			[ 'name' => $name ]
		);
	}

	/**
	 * Get email by ID.
	 *
	 * @since 1.0.0
	 *
	 * @param int $id The email ID.
	 *
	 * @return ?array The email data or null if not found.
	 */
	public function get_by_id( int $id ): ?array {
		return $this->db_handler->get_row(
			$this->db_table->get_prefixed_table_name(),
			[ 'id' => $id ]
		);
	}

	/**
	 * Toggle the enabled status of the email.
	 *
	 * @since 1.0.0
	 *
	 * @return bool True on success, false on failure.
	 * @throws Exception If toggle fails.
	 */
	public function toggle_enabled(): bool {
		$this->is_enabled = ! $this->is_enabled;
		return $this->update();
	}

	/**
	 * Get available contexts for emails.
	 *
	 * @since 1.0.0
	 *
	 * @return array Array of available contexts.
	 */
	public static function get_available_contexts(): array {
		return [
			'member'   => __( 'Member', 'rewardswp' ),
			'referral' => __( 'Referral', 'rewardswp' ),
			'points'   => __( 'Points', 'rewardswp' ),
			'order'    => __( 'Order', 'rewardswp' ),
		];
	}

	/**
	 * Get available recipient types for emails.
	 *
	 * @since 1.0.0
	 *
	 * @return array Array of available recipient types.
	 */
	public static function get_available_recipient_types(): array {
		return [
			'customer' => __( 'Customer', 'rewardswp' ),
			'admin'    => __( 'Admin', 'rewardswp' ),
			'user'     => __( 'User', 'rewardswp' ),
		];
	}

	/**
	 * Get available senders for emails.
	 *
	 * @since 1.0.0
	 *
	 * @return array Array of available senders.
	 */
	public static function get_available_senders(): array {
		return [
			'RewardsWP Core' => __( 'RewardsWP Core', 'rewardswp' ),
			'WordPress'      => __( 'WordPress', 'rewardswp' ),
		];
	}
}
