<?php

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

class Pixelmole_Followup_Emails {
	/** @var Pixelmole_Followup_Plugin */
	private $plugin;

	/** @var Pixelmole_Followup_Logger */
	private $logger;

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

	public function register_hooks() {
		add_action( 'wp_ajax_pixelmole_send_test_email', [ $this, 'ajax_send_test_email' ] );
		add_action( 'wp_ajax_pixelmole_render_preview_email', [ $this, 'ajax_render_preview_email' ] );
		add_action( $this->plugin->get_cron_hook(), [ $this, 'handle_scheduled_email' ] );
		add_action( 'woocommerce_order_status_processing', [ $this, 'schedule_followup_email' ], 10, 1 );
		add_action( 'woocommerce_order_status_completed', [ $this, 'schedule_followup_email' ], 10, 1 );
	}

	public function ajax_send_test_email() {
		check_ajax_referer( $this->plugin->get_nonce_key(), 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( [ 'message' => __( 'Not allowed', 'pixelmole-follow-up-emails' ) ], 403 );
		}

		$to = isset( $_POST['to'] ) ? sanitize_email( wp_unslash( $_POST['to'] ) ) : '';
		if ( ! is_email( $to ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid email address', 'pixelmole-follow-up-emails' ) ] );
		}

		$settings     = $this->plugin->get_settings();
		$replacements = $this->get_test_replacements();

		$subject = strtr( $settings['subject'], $replacements );
		$body    = strtr( $settings['body'], $replacements );

		$headers = $this->build_headers( $settings );
		$sent    = $this->send_email( $to, $subject, $body, $headers, $settings );

		if ( $sent ) {
			$this->logger->log_email( 'test', $to, $subject );
			wp_send_json_success( [ 'message' => __( '✅ Test email sent!', 'pixelmole-follow-up-emails' ) ] );
		}

		wp_send_json_error( [ 'message' => __( 'Failed to send. Please check your email settings or server configuration.', 'pixelmole-follow-up-emails' ) ] );
	}

	public function ajax_render_preview_email() {
		check_ajax_referer( $this->plugin->get_nonce_key(), 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( [ 'message' => __( 'Not allowed', 'pixelmole-follow-up-emails' ) ], 403 );
		}

		$subject = isset( $_POST['subject'] ) ? sanitize_text_field( wp_unslash( $_POST['subject'] ) ) : '';
		$body    = isset( $_POST['body'] )
			? wp_kses( (string) wp_unslash( $_POST['body'] ), $this->get_allowed_preview_tags() )
			: '';

		$subject = $this->normalize_site_url_placeholder( $subject );
		$body    = $this->normalize_site_url_placeholder( $body );

		$replacements = $this->get_test_replacements();
		$subject      = strtr( $subject, $replacements );
		$body         = strtr( $body, $replacements );

		$html = $this->build_preview_html( $subject, $body );

		wp_send_json_success( [ 'html' => $html ] );
	}

	public function schedule_followup_email( $order_id ) {
		if ( ! function_exists( 'wc_get_order' ) ) {
			return;
		}

		$order_id = absint( $order_id );
		if ( ! $order_id ) {
			return;
		}

		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			return;
		}

		if ( 'yes' === $order->get_meta( '_pixelmole_followup_sent', true ) ) {
			return;
		}

		$settings = $this->plugin->get_settings();
		if ( empty( $settings['enabled'] ) ) {
			return;
		}

		$recipient = $order->get_billing_email();
		if ( empty( $recipient ) ) {
			return;
		}

		$delay_seconds = $this->get_delay_seconds( $settings );
		if ( 0 === $delay_seconds ) {
			$this->handle_scheduled_email( $order_id );
			return;
		}

		$timestamp = time() + max( 0, $delay_seconds );

		if ( ! wp_next_scheduled( $this->plugin->get_cron_hook(), [ $order_id ] ) ) {
			wp_schedule_single_event( $timestamp, $this->plugin->get_cron_hook(), [ $order_id ] );
		}

		$order->update_meta_data( '_pixelmole_followup_cancelled', 'no' );
		$order->save();
	}

	public function handle_scheduled_email( $order_id ) {
		if ( ! function_exists( 'wc_get_order' ) ) {
			return;
		}

		$order_id = absint( $order_id );
		if ( ! $order_id ) {
			return;
		}

		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			return;
		}

		if ( 'yes' === $order->get_meta( '_pixelmole_followup_sent', true ) ) {
			return;
		}

		$settings = $this->plugin->get_settings();
		if ( empty( $settings['enabled'] ) ) {
			return;
		}

		$status = $order->get_status();
		if ( in_array( $status, [ 'cancelled', 'refunded', 'failed' ], true ) ) {
			return;
		}

		$recipient = $order->get_billing_email();
		if ( empty( $recipient ) ) {
			return;
		}

		$replacements = $this->get_order_replacements( $order );
		$subject      = strtr( $settings['subject'], $replacements );
		$body         = strtr( $settings['body'], $replacements );
		$headers      = $this->build_headers( $settings );

		$sent = $this->send_email( $recipient, $subject, $body, $headers, $settings );

		if ( $sent ) {
			$this->logger->log_email( 'followup', $recipient, $subject, $order_id );
			$order->update_meta_data( '_pixelmole_followup_sent', 'yes' );
			$order->update_meta_data( '_pixelmole_followup_cancelled', 'no' );
			$order->save();
		}
	}

	private function send_email( $recipient, $subject, $body, $headers, $settings ) {
		$sent = false;

		if ( function_exists( 'WC' ) && WC()->mailer() ) {
			$mailer    = WC()->mailer();
			$body_html = wpautop( $body );
			$wrapped   = $mailer->wrap_message( $subject, $body_html );
			$headers[] = 'Content-Type: text/html; charset=UTF-8';
			$sent      = $mailer->send( $recipient, $subject, $wrapped, $headers );
		} else {
			$headers[] = 'Content-Type: text/html; charset=UTF-8';
			$body      = wpautop( $body );
			$sent      = wp_mail( $recipient, $subject, $body, $headers );
		}

		return (bool) $sent;
	}

	private function build_headers( $settings ) {
		$headers = [];
		if ( ! empty( $settings['from_email'] ) ) {
			$from_name = $settings['from_name'] ?: get_bloginfo( 'name' );
			$headers[] = 'From: ' . $from_name . ' <' . $settings['from_email'] . '>';
		}
		return $headers;
	}

	private function get_delay_seconds( $settings ) {
		$amount = isset( $settings['delay_amount'] ) ? absint( $settings['delay_amount'] ) : 0;
		$unit   = isset( $settings['delay_unit'] ) ? $settings['delay_unit'] : 'days';

		switch ( $unit ) {
			case 'minutes':
				return $amount * MINUTE_IN_SECONDS;
			case 'hours':
				return $amount * HOUR_IN_SECONDS;
			case 'days':
			default:
				return $amount * DAY_IN_SECONDS;
		}
	}

	private function get_test_replacements() {
		return [
			'{{site_name}}'           => wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ),
			'{{site_url}}'            => home_url(),
			'{{customer_first_name}}' => __( 'Test', 'pixelmole-follow-up-emails' ),
			'{{customer_last_name}}'  => __( 'User', 'pixelmole-follow-up-emails' ),
		];
	}

	private function get_order_replacements( $order ) {
		return [
			'{{site_name}}'           => wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ),
			'{{site_url}}'            => home_url(),
			'{{customer_first_name}}' => $order->get_billing_first_name() ?: __( 'klant', 'pixelmole-follow-up-emails' ),
			'{{customer_last_name}}'  => $order->get_billing_last_name() ?: '',
		];
	}

	private function build_preview_html( $subject, $body ) {
		if ( function_exists( 'WC' ) && WC()->mailer() ) {
			$mailer  = WC()->mailer();
			$wrapped = $mailer->wrap_message( $subject, wpautop( $body ) );
			$emails  = $mailer->get_emails();
			$email   = is_array( $emails ) ? reset( $emails ) : null;

			if ( $email && method_exists( $email, 'style_inline' ) ) {
				return $email->style_inline( $wrapped );
			}

			return $wrapped;
		}

		$body_html = wpautop( $body );

		return '<!doctype html><html><head><meta charset="utf-8"><style>body{margin:0;background:#f6f7f7;font-family:Arial,sans-serif;} .wrapper{padding:24px;}</style></head><body><div class="wrapper"><h1 style="font-size:20px;margin:0 0 16px;">' . esc_html( $subject ) . '</h1>' . $body_html . '</div></body></html>';
	}

	private function get_allowed_preview_tags() {
		return [
			'a'      => [
				'href'   => [],
				'title'  => [],
				'target' => [],
				'rel'    => [],
				'class'  => [],
				'style'  => [],
				'role'   => [],
			],
			'button' => [
				'type'   => [],
				'class'  => [],
				'style'  => [],
				'role'   => [],
			],
			'img'    => [
				'src'    => [],
				'alt'    => [],
				'class'  => [],
				'style'  => [],
				'width'  => [],
				'height' => [],
				'srcset' => [],
				'sizes'  => [],
			],
			'div'    => [
				'class' => [],
				'style' => [],
			],
			'span'   => [
				'class' => [],
				'style' => [],
			],
			'br'     => [],
			'hr'     => [],
			'em'     => [],
			'strong' => [],
			'p'      => [
				'class' => [],
				'style' => [],
			],
			'ul'     => [
				'class' => [],
				'style' => [],
			],
			'ol'     => [
				'class' => [],
				'style' => [],
			],
			'li'     => [
				'class' => [],
				'style' => [],
			],
			'table'  => [
				'class'       => [],
				'style'       => [],
				'cellpadding' => [],
				'cellspacing' => [],
				'border'      => [],
				'width'       => [],
			],
			'tbody'  => [],
			'thead'  => [],
			'tfoot'  => [],
			'tr'     => [
				'class' => [],
				'style' => [],
			],
			'td'     => [
				'class'   => [],
				'style'   => [],
				'colspan' => [],
				'rowspan' => [],
			],
			'th'     => [
				'class'   => [],
				'style'   => [],
				'colspan' => [],
				'rowspan' => [],
			],
			'h1'     => [ 'class' => [], 'style' => [] ],
			'h2'     => [ 'class' => [], 'style' => [] ],
			'h3'     => [ 'class' => [], 'style' => [] ],
			'h4'     => [ 'class' => [], 'style' => [] ],
			'h5'     => [ 'class' => [], 'style' => [] ],
			'h6'     => [ 'class' => [], 'style' => [] ],
		];
	}

	private function normalize_site_url_placeholder( $value ) {
		$patterns = [
			'https://{{site_url}}',
			'http://{{site_url}}',
		];

		return str_replace( $patterns, '{{site_url}}', $value );
	}
}
