<?php

namespace Limb_Chatbot\Includes\Services\Actions;

use Limb_Chatbot\Includes\Data_Objects\Chatbot_User;
use Limb_Chatbot\Includes\Exceptions\Error_Codes;
use Limb_Chatbot\Includes\Exceptions\Exception;
use Limb_Chatbot\Includes\Services\User_Manager;

/**
 * Class Email_Verification_Service
 *
 * Handles email verification workflow including code generation,
 * sending verification emails, and validating codes.
 *
 * @package Limb_Chatbot\Includes\Services\Actions
 * @since 1.0.0
 */
class Email_Verification_Service {

	/**
	 * Verification code length
	 */
	const CODE_LENGTH = 6;

	/**
	 * Verification code expiry time in seconds (15 minutes)
	 */
	const CODE_EXPIRY = 900;

	/**
	 * Meta key prefix for storing verification codes
	 */
	const META_PREFIX = 'email_verification_';

	/**
	 * Generate a random verification code
	 *
	 * @return string Six-digit code
	 * @since 1.0.0
	 */
	public function generate_code(): string {
		return str_pad( (string) wp_rand( 0, 999999 ), self::CODE_LENGTH, '0', STR_PAD_LEFT );
	}

	/**
	 * Send verification email with code
	 *
	 * @param string $email Email address to send to
	 * @param string $code Verification code
	 *
	 * @return bool True if email was sent successfully
	 * @throws Exception If email sending fails
	 * @since 1.0.0
	 */
	public function send_verification_email( string $email, string $code ): bool {
		$email = sanitize_email( $email );

		if ( ! is_email( $email ) ) {
			throw new Exception(Error_Codes::VALIDATION_INVALID_VALUE,  __( 'Invalid email address', 'limb-chatbot' ) );
		}

		$subject = $this->build_subject_with_identifier( __( 'Email Verification Code', 'limb-chatbot' ), $email );
		$body    = $this->get_email_body( $code, $email );
		$headers = $this->get_email_headers();

		$result = wp_mail( $email, $subject, $body, $headers );

		if ( ! $result ) {
			throw new Exception(Error_Codes::TECHNICAL_ERROR, __( 'Failed to send verification email', 'limb-chatbot' ) );
		}

		return true;
	}

	/**
	 * Save verification code to user meta
	 *
	 * @param string $code Verification code
	 * @param string $email Email being verified
	 *
	 * @return void
	 * @throws Exception
	 * @since 1.0.0
	 */
	public function save_verification_code( string $code, string $email ): void {
		$user = User_Manager::instance()->get_current_user();

		if ( ! $user instanceof Chatbot_User ) {
			throw new Exception( Error_Codes::NOT_FOUND, __( 'User not found', 'limb-chatbot' ) );
		}

		$meta_key  = self::META_PREFIX . md5( $email );
		$meta_data = [
			'code'       => $code,
			'email'      => $email,
			'expires_at' => time() + self::CODE_EXPIRY,
			'verified'   => false,
		];

		$user->update_meta( $meta_key, wp_json_encode( $meta_data ) );
	}

	/**
	 * Verify the provided code
	 *
	 * @param string $provided_code Code provided by user
	 * @param string $email Email being verified
	 *
	 * @return bool True if code is valid
	 * @throws Exception If verification fails
	 * @since 1.0.0
	 */
	public function verify_code( string $provided_code, string $email ): bool {
		try {
			$user = User_Manager::instance()->get_current_user();

			if ( ! $user instanceof Chatbot_User ) {
				throw new Exception(Error_Codes::NOT_FOUND, __( 'User not found', 'limb-chatbot' ) );
			}

			$meta_key  = self::META_PREFIX . md5( $email );
			$data = $user->get_meta( $meta_key );

			if ( ! $data ) {
				throw new Exception(Error_Codes::NOT_FOUND, __( 'No verification code found for this email', 'limb-chatbot' ) );
			}

			// Check if code has expired
			if ( time() > $data['expires_at'] ) {
				throw new Exception(Error_Codes::AUTHENTICATION_UNAUTHORIZED, __( 'Verification code has expired', 'limb-chatbot' ) );
			}

			// Check if codes match
			if ( $data['code'] !== $provided_code ) {
				throw new Exception(Error_Codes::VALIDATION_INVALID_VALUE, __( 'Invalid verification code', 'limb-chatbot' ) );
			}

			// Mark as verified
			$data['verified'] = true;
			$user->update_meta( $meta_key, wp_json_encode( $data ) );

			return true;
		} catch ( Exception $e ) {
			throw $e;
		}
	}

	/**
	 * Check if email is already verified in current session
	 *
	 * @param string $email Email to check
	 *
	 * @return bool True if email is verified
	 * @since 1.0.0
	 */
	public function is_email_verified( string $email ): bool {
		try {
			$user = User_Manager::instance()->get_current_user();

			if ( ! $user instanceof Chatbot_User ) {
				return false;
			}

			$meta_key  = self::META_PREFIX . md5( $email );
			$meta_data = $user->get_meta( $meta_key );

			if ( ! $meta_data ) {
				return false;
			}

			$data = json_decode( $meta_data, true );

			return isset( $data['verified'] ) && $data['verified'] === true;
		} catch ( Exception $e ) {
			return false;
		}
	}

	/**
	 * Get email body with verification code
	 *
	 * @param string $code Verification code
	 * @param string $email Recipient email
	 *
	 * @return string HTML email body
	 * @since 1.0.0
	 */
	private function get_email_body( string $code, string $email ): string {
		$site_name = get_bloginfo( 'name' );

		// Get base color from WordPress theme
		$primary_color = '#3498db';

		ob_start();
		?>
<!DOCTYPE html>
<html lang="<?php echo esc_attr( get_locale() ); ?>">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title><?php esc_html_e( 'Email Verification', 'limb-chatbot' ); ?></title>
	<style>
		body {
			font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
			line-height: 1.6;
			color: #333;
			background-color: #f5f5f5;
			margin: 0;
			padding: 0;
		}
		.container {
			max-width: 500px;
			margin: 20px auto;
			background: white;
			border-radius: 8px;
			box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
			overflow: hidden;
		}
		.header {
			background: linear-gradient(135deg, <?php echo esc_attr( $primary_color ); ?> 0%, #2980b9 100%);
			color: white;
			padding: 30px 20px;
			text-align: center;
		}
		.header h1 {
			margin: 0;
			font-size: 24px;
			font-weight: 600;
		}
		.content {
			padding: 30px 20px;
		}
		.greeting {
			font-size: 16px;
			margin-bottom: 20px;
			color: #555;
		}
		.code-section {
			background: #f8f9fa;
			border-left: 4px solid <?php echo esc_attr( $primary_color ); ?>;
			padding: 20px;
			margin: 20px 0;
			border-radius: 4px;
			text-align: center;
		}
		.verification-code {
			font-size: 32px;
			font-weight: bold;
			letter-spacing: 5px;
			color: <?php echo esc_attr( $primary_color ); ?>;
			margin: 15px 0;
			font-family: 'Courier New', monospace;
		}
		.expiry-info {
			font-size: 13px;
			color: #999;
			margin-top: 15px;
		}
		.info-text {
			font-size: 14px;
			color: #666;
			margin: 20px 0;
			line-height: 1.8;
		}
		.footer {
			background: #f8f9fa;
			padding: 20px;
			text-align: center;
			font-size: 12px;
			color: #999;
			border-top: 1px solid #e0e0e0;
		}
		.footer a {
			color: <?php echo esc_attr( $primary_color ); ?>;
			text-decoration: none;
		}
	</style>
</head>
<body>
	<div class="container">
		<div class="header">
			<h1><?php esc_html_e( 'Verify Your Email', 'limb-chatbot' ); ?></h1>
		</div>
		<div class="content">
			<p class="greeting">
				<?php esc_html_e( 'Hello,', 'limb-chatbot' ); ?>
			</p>
			<p class="info-text">
				<?php
				echo sprintf(
					/* translators: %s: site name */
					esc_html__( 'Thank you for using %s. Please use the verification code below to confirm your email address.', 'limb-chatbot' ),
					esc_html( $site_name )
				);
				?>
			</p>
			<div class="code-section">
				<p style="margin: 0 0 10px 0; color: #666;">
					<?php esc_html_e( 'Your Verification Code:', 'limb-chatbot' ); ?>
				</p>
				<div class="verification-code"><?php echo esc_html( $code ); ?></div>
				<p class="expiry-info">
					<?php
					echo sprintf(
						/* translators: %d: number of minutes */
						esc_html__( 'This code will expire in %d minutes.', 'limb-chatbot' ),
						intdiv( self::CODE_EXPIRY, 60 )
					);
					?>
				</p>
			</div>
			<p class="info-text">
				<?php esc_html_e( 'If you did not request this verification code, please ignore this email. Your email address will not be verified if you do not provide this code.', 'limb-chatbot' ); ?>
			</p>
		</div>
		<div class="footer">
			<p>
				<?php
				echo sprintf(
					/* translators: %s: site name, %s: site URL */
					wp_kses_post( __( '© 2024 %1$s. All rights reserved. <a href="%2$s">Visit our website</a>', 'limb-chatbot' ) ),
					esc_html( $site_name ),
					esc_url( home_url() )
				);
				?>
			</p>
		</div>
	</div>
</body>
</html>
		<?php
		return ob_get_clean();
	}

	/**
	 * Get email headers for verification email
	 *
	 * @return array Email headers
	 * @since 1.0.0
	 */
	private function get_email_headers(): array {
		$headers = [
			'Content-Type: text/html; charset=UTF-8',
			'From: ' . get_option( 'admin_email' ),
		];

		return $headers;
	}

	/**
	 * Add a short subject identifier for verification emails.
	 *
	 * @param string $subject
	 * @param string $email
	 * @return string
	 */
	private function build_subject_with_identifier( string $subject, string $email ): string {
		$user = User_Manager::instance()->get_current_user();
		if ( $user instanceof Chatbot_User && $user->get_id() ) {
			return sprintf( '%s [#%d]', $subject, (int) $user->get_id() );
		}

		return $subject;
	}
}
