<?php
/**
 * PDF Document Handler Class
 *
 * This class provides comprehensive functionality for handling PDF operations in the SureForms Pro plugin.
 * It manages the entire PDF workflow including:
 * - DOCX template processing and smart tag extraction
 * - PDF generation and conversion
 * - File management and storage
 * - Template variable replacement
 *
 * The class integrates with PhpWord for DOCX processing and DomPDF for PDF generation,
 * providing a robust solution for dynamic PDF creation from templates.
 *
 * @since 1.9.0
 * @package sureforms-pro
 */

namespace SRFM_Pro\Inc\Business\Pdf;

use SRFM\Inc\Smart_Tags;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;

// Load the autoloader. if library exists.
if ( Utils::check_if_library_exists() ) {
	require_once WP_PLUGIN_DIR . '/sureforms-libraries/pdf/vendor/autoload.php';
}

/**
 * Document Class
 *
 * Core class responsible for PDF document operations in SureForms Pro.
 * Handles template processing, smart tag replacement, and PDF generation.
 *
 * @since 1.9.0
 */
class Document {
	/**
	 * Array of PDF items as tags.
	 * Store the pdf items as tags.
	 * key will be the slug of the pdf item.
	 * value will be the pdf item.
	 *
	 * @since 1.9.0
	 * @var array
	 */
	public static $pdf_items_as_tags = [];

	/**
	 * Process the pdf item.
	 *
	 * @param array  $pdf_item PDF configuration data.
	 * @param array  $form_data Form configuration data.
	 * @param array  $submission_data User-submitted form data.
	 * @param string $smart_tag Smart tag.
	 *
	 * @since 1.9.0
	 * @return string Path to the generated PDF file, empty string on failure
	 */
	public static function process_pdf_item( $pdf_item, $form_data, $submission_data, $smart_tag ) {
		if ( empty( $pdf_item ) ) {
			return '';
		}

		if ( empty( $pdf_item['templateType'] ) ) {
			return '';
		}

		// Extract the form item from the form data.
		$form_id                      = $form_data['form-id'] ?? '';
		$stored_value_tag_and_form_id = $smart_tag . '_' . $form_id;

		// Check if the pdf item is already processed.
		if ( isset( self::$pdf_items_as_tags[ $stored_value_tag_and_form_id ] ) ) {
			return self::$pdf_items_as_tags[ $stored_value_tag_and_form_id ];
		}

		if ( 'generic' === $pdf_item['templateType'] ) {
			$pdf_link = self::process_generic_pdf( $pdf_item, $form_data, $submission_data );
		}

		if ( ! empty( $pdf_link ) ) {
			self::$pdf_items_as_tags[ $stored_value_tag_and_form_id ] = $pdf_link;
			return $pdf_link;
		}

		return '';
	}

	/**
	 * Process generic PDF template.
	 *
	 * Handles the generation of PDFs using the default template system.
	 * This is a placeholder for the standard PDF processing implementation.
	 *
	 * @param array $pdf_item PDF configuration data.
	 * @param array $form_data Form configuration data.
	 * @param array $submission_data User-submitted form data.
	 *
	 * @since 1.9.0
	 * @return string Path to the generated PDF file, empty string on failure
	 */
	public static function process_generic_pdf( $pdf_item, $form_data, $submission_data ) {
		// Implementation for standard PDF processing.
		$generic_pdf_meta = $pdf_item['generic'] ?? [];

		if ( empty( $generic_pdf_meta ) ) {
			return '';
		}

		$pdf_content = $generic_pdf_meta['pdfContent'] ?? '';

		// If the pdf content is not a string, then decode it.
		if ( empty( $pdf_content ) || ! is_string( $pdf_content ) ) {
			return '';
		}

		// Process the smart tags in the pdf content.
		$smart_tags = new Smart_Tags();

		// Add the key pdf_generation to the form data.
		$form_data['pdf_generation'] = true;

		$pdf_content = $smart_tags->process_smart_tags( $pdf_content, $submission_data, $form_data );

		// Check class exists.
		if ( ! class_exists( '\Mpdf\Mpdf' ) ) {
			return '';
		}

		$config = self::get_mpdf_config( $generic_pdf_meta );

		// Create a temporary HTML file. by mpdf library.
		$mpdf          = new \Mpdf\Mpdf( $config );
		$random_string = strtolower( wp_generate_password( 10, false ) );

		$pdf_title = sanitize_title( strtolower( trim( $generic_pdf_meta['name'] ) ) );
		if ( empty( $pdf_title ) ) {
			$pdf_title = 'pdf';
		}

		// Check if the pdf directory exists and create if not.
		self::check_pdf_directory();

		$pdf_file_name = sanitize_file_name( 'srfm-' . $random_string . '-' . $pdf_title . '.pdf' );
		$pdf_file_path = Utils::pdf_file_dir( 'path' ) . '/' . $pdf_file_name;

		// Add the default styles to the pdf content.
		$default_styles = '<style>' . Utils::editor_default_styles() . '</style>';

		$pdf_content = $default_styles . $pdf_content;

		// Set password if any.
		if ( ! empty( $generic_pdf_meta['pdfPassword'] ) ) {
			// Trim the password.
			$password = trim( $generic_pdf_meta['pdfPassword'] );

			if ( ! empty( $password ) ) {
				// Set the password.
				$mpdf->SetProtection( [ 'print', 'copy', 'modify' ], $password, $password );
			}
		}

		// Write the pdf content to the file.
		$mpdf->WriteHTML( $pdf_content );
		$mpdf->Output( $pdf_file_path, 'F' );

		// Return the download link.
		return Utils::pdf_file_dir( 'url' ) . '/' . $pdf_file_name;
	}

	/**
	 * Create the mpdf font data.
	 *
	 * @since 1.9.0
	 * @return array
	 */
	public static function configure_mpdf_font_data() {
		$font_dir = WP_PLUGIN_DIR . '/sureforms-libraries/pdf/fonts';

		if ( ! file_exists( $font_dir ) ) {
			return [];
		}

		return [
			// Courier Prime.
			'courierprime'  => [
				'R' => 'CourierPrime-Regular.ttf',
				'B' => 'CourierPrime-Bold.ttf',
			],
			'courier prime' => 'courierprime',

			// Figtree.
			'figtree'       => [
				'R' => 'Figtree-Regular.ttf',
				'B' => 'Figtree-Bold.ttf',
				'M' => 'Figtree-Medium.ttf',
			],

			// Inter (18pt).
			'inter'         => [
				'R' => 'Inter_18pt-Regular.ttf',
				'B' => 'Inter_18pt-Bold.ttf',
				'M' => 'Inter_18pt-Medium.ttf',
			],

			// Lato.
			'lato'          => [
				'R' => 'Lato-Regular.ttf',
				'B' => 'Lato-Bold.ttf',
			],

			// Merriweather (24pt & 36pt).
			'merriweather'  => [
				'R' => 'Merriweather_24pt-Regular.ttf',
				'B' => 'Merriweather_24pt-Bold.ttf',
				'M' => 'Merriweather_36pt-Medium.ttf',
			],

			// Montserrat.
			'montserrat'    => [
				'R' => 'Montserrat-Regular.ttf',
				'B' => 'Montserrat-Bold.ttf',
				'M' => 'Montserrat-Medium.ttf',
			],

			// Noto Sans.
			'notosans'      => [
				'R' => 'NotoSans-Regular.ttf',
				'B' => 'NotoSans-Bold.ttf',
				'M' => 'NotoSans-Medium.ttf',
			],
			'noto sans'     => 'notosans',

			// Poppins.
			'poppins'       => [
				'R' => 'Poppins-Regular.ttf',
				'B' => 'Poppins-Bold.ttf',
				'M' => 'Poppins-Medium.ttf',
			],

			// Roboto Mono.
			'robotomono'    => [
				'R' => 'RobotoMono-Regular.ttf',
				'B' => 'RobotoMono-Bold.ttf',
				'M' => 'RobotoMono-Medium.ttf',
			],
			'roboto mono'   => 'robotomono',

			// Work Sans.
			'worksans'      => [
				'R' => 'WorkSans-Regular.ttf',
				'B' => 'WorkSans-Bold.ttf',
				'M' => 'WorkSans-Medium.ttf',
			],
			'work sans'     => 'worksans',
		];
	}

	/**
	 * Get the mpdf font directory.
	 *
	 * @since 1.9.0
	 * @return array
	 */
	public static function get_mpdf_font_dir() {
		return [
			WP_PLUGIN_DIR . '/sureforms-libraries/pdf/fonts',
		];
	}

	/**
	 * Get the mpdf config.
	 *
	 * @param array $generic_pdf_meta Generic PDF meta data.
	 *
	 * @since 1.9.0
	 * @return array
	 */
	public static function get_mpdf_config( $generic_pdf_meta ) {
		$format      = $generic_pdf_meta['paperSize'] ?? 'A4';
		$orientation = 'portrait' === $generic_pdf_meta['paperOrientation'] ? 'P' : 'L';

		// Get the base upload directory using WordPress API.
		$upload_dir = wp_upload_dir();
		$temp_dir   = trailingslashit( $upload_dir['basedir'] ) . 'sureforms/temp';

		$config = [
			'mode'            => 'utf-8',
			'format'          => $format,
			'margin_left'     => 4,
			'margin_right'    => 4,
			'margin_top'      => 4,
			'margin_bottom'   => 4,
			'margin_header'   => 0,
			'margin_footer'   => 0,
			'debugfonts'      => false,
			'debug'           => false,
			'fontdata'        => self::configure_mpdf_font_data(),
			'fontDir'         => array_merge(
				self::get_mpdf_font_dir()
			),
			'default_font'    => 'figtree',
			'orientation'     => $orientation,
			'tempDir'         => $temp_dir,
			'showImageErrors' => false,
			'defaultImage'    => '',
		];

		return apply_filters( 'srfm_pro_mpdf_config', $config );
	}

	/**
	 * Check if PDF directory exists and create if not.
	 *
	 * @since 1.9.0
	 * @return bool True if directory exists or was created successfully, false otherwise.
	 */
	public static function check_pdf_directory() {
		$pdf_dir = Utils::pdf_file_dir();

		// Return true if directory already exists.
		if ( file_exists( $pdf_dir ) ) {
			return true;
		}

		// Try to create the directory.
		$created = wp_mkdir_p( $pdf_dir );

		// Set proper permissions if directory was created.
		if ( $created ) {
			chmod( $pdf_dir, 0755 );
		}

		return $created;
	}
}
