<?php
/**
 * Email notification handler.
 *
 * @package MerchantKits\AttendanceManager
 */

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

/**
 * Sends theme-overridable HTML emails and wires notification triggers.
 */
class MKAM_Email {

	/**
	 * Hook notification triggers to plugin actions.
	 */
	public function __construct() {
		add_action( 'mkam_leave_requested', array( $this, 'on_leave_requested' ), 10, 2 );
		add_action( 'mkam_leave_approved', array( $this, 'on_leave_approved' ), 10, 3 );
		add_action( 'mkam_leave_rejected', array( $this, 'on_leave_rejected' ), 10, 3 );
		add_action( 'mkam_clock_in', array( $this, 'on_clock_in' ), 10, 2 );
	}

	/**
	 * Send an email of a given type using a template.
	 *
	 * @param string $type      Email type / template slug.
	 * @param string $recipient Recipient email address.
	 * @param array  $data      Template data.
	 * @return bool
	 */
	public function send( $type, $recipient, $data = array() ) {
		$recipient = sanitize_email( $recipient );

		if ( ! is_email( $recipient ) ) {
			return false;
		}

		$recipients = apply_filters( 'mkam_email_recipients', array( $recipient ), $type );
		$subject    = apply_filters( 'mkam_email_subject', $this->default_subject( $type, $data ), $type );
		$content    = apply_filters( 'mkam_email_content', $this->render_template( $type, $data ), $type );

		if ( '' === $content ) {
			return false;
		}

		$headers = array( 'Content-Type: text/html; charset=UTF-8' );

		do_action( 'mkam_before_email_send', $type, $recipients, $data );

		$success = wp_mail( $recipients, $subject, $content, $headers );

		do_action( 'mkam_after_email_send', $type, $recipients, $success );

		return (bool) $success;
	}

	/**
	 * Resolve the default subject line for an email type.
	 *
	 * @param string $type Email type.
	 * @param array  $data Template data.
	 * @return string
	 */
	private function default_subject( $type, $data ) {
		$company = get_option( 'mkam_company_name', get_bloginfo( 'name' ) );

		switch ( $type ) {
			case 'clock_in_confirmation':
				return sprintf( '[%s] %s', $company, __( 'Clock-in confirmation', 'merchantkits-attendance-manager' ) );
			case 'leave_request_submitted':
				return sprintf( '[%s] %s', $company, __( 'New leave request', 'merchantkits-attendance-manager' ) );
			case 'leave_request_approved':
				return sprintf( '[%s] %s', $company, __( 'Your leave request was approved', 'merchantkits-attendance-manager' ) );
			case 'leave_request_rejected':
				return sprintf( '[%s] %s', $company, __( 'Your leave request was rejected', 'merchantkits-attendance-manager' ) );
			case 'attendance_summary':
				return sprintf( '[%s] %s', $company, __( 'Attendance summary', 'merchantkits-attendance-manager' ) );
			default:
				return $company;
		}
	}

	/**
	 * Locate a template (theme override first) and render it to a string.
	 *
	 * @param string $type Email template slug.
	 * @param array  $data Variables exposed to the template.
	 * @return string
	 */
	private function render_template( $type, $data ) {
		$file = str_replace( '_', '-', $type ) . '.php';

		$theme_path = trailingslashit( get_stylesheet_directory() ) . 'mkam/email/' . $file;
		$plugin_path = MKAM_TEMPLATES_DIR . 'email/' . $file;

		$template = is_readable( $theme_path ) ? $theme_path : $plugin_path;

		if ( ! is_readable( $template ) ) {
			return '';
		}

		// phpcs:ignore WordPress.PHP.DontExtract.extract_extract
		extract( $data );

		ob_start();
		include $template;
		$body = ob_get_clean();

		return $this->wrap( $body );
	}

	/**
	 * Wrap body content with a branded header and footer.
	 *
	 * @param string $body Inner HTML.
	 * @return string
	 */
	private function wrap( $body ) {
		$company = esc_html( get_option( 'mkam_company_name', get_bloginfo( 'name' ) ) );
		$settings_url = esc_url( admin_url( 'admin.php?page=mkam-settings&tab=notifications' ) );

		$header = '<div style="font-family:Arial,sans-serif;max-width:600px;margin:0 auto;">'
			. '<div style="background:#2563eb;color:#fff;padding:16px 24px;font-size:18px;font-weight:bold;">' . $company . '</div>'
			. '<div style="padding:24px;color:#1f2937;line-height:1.6;">';

		$footer = '</div><div style="padding:16px 24px;color:#6b7280;font-size:12px;border-top:1px solid #e5e7eb;">'
			. esc_html__( 'You are receiving this notification from MerchantKits Attendance Manager.', 'merchantkits-attendance-manager' )
			. ' <a href="' . $settings_url . '">' . esc_html__( 'Manage notifications', 'merchantkits-attendance-manager' ) . '</a>'
			. '</div></div>';

		return $header . $body . $footer;
	}

	/* ---------------------------------------------------------------------
	 * Trigger callbacks
	 * ------------------------------------------------------------------- */

	/**
	 * Notify the admin when a leave request is submitted.
	 *
	 * @param int $leave_id    Leave ID.
	 * @param int $employee_id Employee ID.
	 * @return void
	 */
	public function on_leave_requested( $leave_id, $employee_id ) {
		if ( ! get_option( 'mkam_notify_admin_leave_request', 1 ) ) {
			return;
		}

		$recipient = get_option( 'mkam_admin_email', get_option( 'admin_email' ) );
		$this->send(
			'leave_request_submitted',
			$recipient,
			array(
				'leave'    => MKAM_Leave::get( $leave_id ),
				'employee' => MKAM_Employee::get( $employee_id ),
			)
		);
	}

	/**
	 * Notify the employee when their leave is approved.
	 *
	 * @param int $leave_id    Leave ID.
	 * @param int $employee_id Employee ID.
	 * @return void
	 */
	public function on_leave_approved( $leave_id, $employee_id ) {
		$this->notify_employee_decision( 'leave_request_approved', $leave_id, $employee_id );
	}

	/**
	 * Notify the employee when their leave is rejected.
	 *
	 * @param int $leave_id    Leave ID.
	 * @param int $employee_id Employee ID.
	 * @return void
	 */
	public function on_leave_rejected( $leave_id, $employee_id ) {
		$this->notify_employee_decision( 'leave_request_rejected', $leave_id, $employee_id );
	}

	/**
	 * Shared leave-decision notification.
	 *
	 * @param string $type        Email type.
	 * @param int    $leave_id    Leave ID.
	 * @param int    $employee_id Employee ID.
	 * @return void
	 */
	private function notify_employee_decision( $type, $leave_id, $employee_id ) {
		if ( ! get_option( 'mkam_notify_employee_leave_decision', 1 ) ) {
			return;
		}

		$employee = MKAM_Employee::get( $employee_id );

		if ( ! $employee || empty( $employee['email'] ) ) {
			return;
		}

		$this->send(
			$type,
			$employee['email'],
			array(
				'leave'    => MKAM_Leave::get( $leave_id ),
				'employee' => $employee,
			)
		);
	}

	/**
	 * Optionally confirm a clock-in to the employee and/or admin.
	 *
	 * @param int $attendance_id Attendance ID.
	 * @param int $employee_id   Employee ID.
	 * @return void
	 */
	public function on_clock_in( $attendance_id, $employee_id ) {
		$employee = MKAM_Employee::get( $employee_id );

		if ( $employee && ! empty( $employee['email'] ) ) {
			$this->send(
				'clock_in_confirmation',
				$employee['email'],
				array(
					'attendance' => MKAM_Attendance::get( $attendance_id ),
					'employee'   => $employee,
				)
			);
		}

		if ( get_option( 'mkam_notify_admin_clock_in', 0 ) ) {
			$this->send(
				'clock_in_confirmation',
				get_option( 'mkam_admin_email', get_option( 'admin_email' ) ),
				array(
					'attendance' => MKAM_Attendance::get( $attendance_id ),
					'employee'   => $employee,
				)
			);
		}
	}
}
