<?php

namespace Limb_Chatbot\Includes\Services\Actions\Parameter_Types;

use Limb_Chatbot\Includes\Data_Objects\Action_Plan_Step;
use Limb_Chatbot\Includes\Data_Objects\Parameter;
use Limb_Chatbot\Includes\Exceptions\Error_Codes;
use Limb_Chatbot\Includes\Exceptions\Exception;
use Limb_Chatbot\Includes\Services\Actions\Email_Verification_Service;

/**
 * Class Email_Parameter_Type
 *
 * Handles email parameter validation, sanitization, and optional verification.
 * Uses WordPress native email validation.
 *
 * Supports post-collection verification when config has "verify": 1
 *
 * @package Limb_Chatbot\Includes\Services\Actions\Parameter_Types
 * @since 1.0.0
 */
class Email_Parameter_Type extends Abstract_Parameter_Type {

	/**
	 * Verification service
	 *
	 * @var Email_Verification_Service
	 */
	private Email_Verification_Service $verification_service;

	/**
	 * Constructor
	 *
	 * @param  Email_Verification_Service|null  $verification_service  Optional verification service
	 */
	public function __construct( ?Email_Verification_Service $verification_service = null ) {
		$this->verification_service = $verification_service ?? new Email_Verification_Service();
	}

	/**
	 * @inheritDoc
	 */
	public function get_type(): string {
		return Parameter::TYPE_EMAIL;
	}

	/**
	 * @inheritDoc
	 */
	public function get_config_schema(): array {
		return [
			'verify' => [
				'type'        => 'boolean',
				'description' => 'Require email verification',
				'required'    => false,
			],
			'lead_capture_map_field' => array(
				'type'        => 'integer',
				'description' => 'Lead capture map field',
				'required'    => false,
			),
		];
	}

	/**
	 * @inheritDoc
	 */
	public function sanitize( string $value, Parameter $parameter ): string {
		return sanitize_email( trim( $value ) );
	}

	/**
	 * @inheritDoc
	 */
	public function validate( string $value, Parameter $parameter ): bool {
		$this->clear_errors();

		$trimmed_value = trim( $value );

		// Check if field is empty
		if ( empty( $trimmed_value ) ) {
			// If empty and required, show required error
			if ( $this->is_required( $parameter ) ) {
				$this->add_error( sprintf(
					__( '%s is required.', 'limb-chatbot' ),
					$this->get_label( $parameter )
				) );

				return false;
			}

			// If empty and not required, it's valid
			return true;
		}

		// Field has value, validate format
		if ( ! is_email( $trimmed_value ) ) {
			$this->add_error( sprintf(
				__( 'Please provide a valid email address for %s.', 'limb-chatbot' ),
				$this->get_label( $parameter )
			) );

			return false;
		}

		return true;
	}

	/**
	 * @inheritDoc
	 */
	public function get_hint( Parameter $parameter ): ?string {
		$placeholder = $parameter->get_placeholder();

		return sprintf(
			__( 'For example: %s', 'limb-chatbot' ),
			$placeholder ?: 'user@example.com'
		);
	}

	/**
	 * @inheritDoc
	 */
	public function has_post_collection_steps( Parameter $parameter ): bool {
		return $this->should_verify_email( $parameter );
	}

	/**
	 * Check if email verification is required
	 *
	 * @param  Parameter  $parameter  The parameter configuration
	 *
	 * @return bool True if verification is enabled
	 * @since 1.0.0
	 */
	private function should_verify_email( Parameter $parameter ): bool {
		$config = $parameter->get_config();
		if ( ! is_array( $config ) ) {
			return false;
		}

		return isset( $config['verify'] ) && $config['verify'] == 1;
	}

	/**
	 * @inheritDoc
	 */
	public function get_post_collection_step_type( Parameter $parameter ): ?int {
		if ( ! $this->should_verify_email( $parameter ) ) {
			return null;
		}

		return Action_Plan_Step::TYPE_EMAIL_VERIFICATION;
	}

	/**
	 * @inheritDoc
	 */
	public function get_post_collection_step_data( Parameter $parameter, string $collected_value ): array {
		// Generate verification code
		$code = $this->verification_service->generate_code();

		// Send verification email
		$this->verification_service->send_verification_email( $collected_value, $code );

		// Save verification code to user meta
		$this->verification_service->save_verification_code( $code, $collected_value );

		return [
			'parameter'        => $parameter,
			'email'            => $collected_value,
			'email_field_name' => $parameter->get_name(),
		];
	}

	/**
	 * @inheritDoc
	 */
	public function process_post_collection_step( Parameter $parameter, array $step_data, string $user_input ) {
		$email = $step_data['email'] ?? null;

		if ( empty( $email ) ) {
			throw new Exception( Error_Codes::NOT_FOUND, __( 'Email not found in verification step', 'limb-chatbot' ) );
		}

		// Validate the verification code
		$this->verification_service->verify_code( trim( $user_input ), $email );
	}
}

