<?php
/**
 * PDF Generator
 *
 * Generates PDF receipts using Dompdf.
 *
 * @package DonorCore\Receipts
 */

namespace DonorCore\Receipts;

defined( 'ABSPATH' ) || exit;

use Dompdf\Dompdf;
use Dompdf\Options;

/**
 * PDF Generator Class
 */
class PDF_Generator {

	/**
	 * Generate PDF receipt for an order.
	 *
	 * @param int    $order_id Order ID.
	 * @param string $template Template name.
	 * @return string|false File path on success, false on failure.
	 */
	public function generate( $order_id, $template = 'default' ) {
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return false;
		}

		// Load template.
		$html = $this->load_template( $order );

		if ( ! $html ) {
			return false;
		}

		// Configure Dompdf.
		$options = new Options();
		$options->set( 'isRemoteEnabled', true );
		$options->set( 'defaultFont', 'DejaVu Sans' );

		$dompdf = new Dompdf( $options );
		$dompdf->loadHtml( $html );
		$dompdf->setPaper( 'A4', 'portrait' );
		$dompdf->render();

		// Save to file.
		$file_path = $this->get_receipt_path( $order_id );
		$this->ensure_directory_exists();
		$this->create_htaccess_protection();

		file_put_contents( $file_path, $dompdf->output() );

		return $file_path;
	}

	/**
	 * Load and populate HTML template.
	 *
	 * @param \WC_Order $order Order object.
	 * @return string|false
	 */
	private function load_template( $order ) {
		// Get saved template sections from settings
		$header = $this->sanitize_pdf_html( get_option( 'donorcore_pdf_header', '' ) );
		$body   = $this->sanitize_pdf_html( get_option( 'donorcore_pdf_body', '' ) );
		$footer = $this->sanitize_pdf_html( get_option( 'donorcore_pdf_footer', '' ) );

		// If no custom body, load default template
		if ( empty( $body ) ) {
			$body = $this->get_default_pdf_template();
		}

		// Self-healing check: if legacy DB option had <style> stripped around CSS rules, repair it
		if ( ! empty( $body ) && strpos( $body, '<style' ) === false && strpos( $body, '@page' ) !== false ) {
			$body = '<style>' . $body;
			if ( strpos( $body, '<div class="container">' ) !== false ) {
				$body = str_replace( '<div class="container">', '</style><div class="container">', $body );
			} else {
				$body .= '</style>';
			}
		}

		// Combine header, body, footer
		$html = $header . $body . $footer;

		// Replace placeholders with actual values
		return $this->replace_placeholders( $html, $order );
	}

	/**
	 * Sanitize PDF HTML template preserving CSS <style> tags and document elements.
	 *
	 * @param string $content HTML content.
	 * @return string Sanitized HTML.
	 */
	private function sanitize_pdf_html( $content ) {
		if ( empty( $content ) ) {
			return '';
		}

		$allowed_html = wp_kses_allowed_html( 'post' );

		// Allow style tag and standard document tags for Dompdf rendering
		$allowed_html['style'] = array(
			'type'  => true,
			'media' => true,
		);
		$allowed_html['html'] = array(
			'xmlns' => true,
			'lang'  => true,
		);
		$allowed_html['head'] = array();
		$allowed_html['body'] = array(
			'class' => true,
			'id'    => true,
			'style' => true,
		);
		$allowed_html['meta'] = array(
			'charset'    => true,
			'name'       => true,
			'content'    => true,
			'http-equiv' => true,
			'viewport'   => true,
		);

		return wp_kses( $content, $allowed_html );
	}

	/**
	 * Get default PDF template.
	 *
	 * @return string
	 */
	private function get_default_pdf_template() {
		$template_file = DONOR_CORE_PLUGIN_DIR . 'includes/Receipts/templates/pdf-default.html';

		if ( file_exists( $template_file ) ) {
			return file_get_contents( $template_file );
		}

		// Fallback if file doesn't exist
		return '<html><body><h1>Donation Receipt</h1><p>Amount: {amount}</p></body></html>';
	}

	/**
	 * Replace placeholders with actual values.
	 *
	 * @param string    $html  Template HTML.
	 * @param \WC_Order $order Order object.
	 * @return string
	 */
	private function replace_placeholders( $html, $order ) {
		// Get donation details.
		$amount      = 0;
		$campaign    = '';
		$campaign_id = 0;

		foreach ( $order->get_items() as $item ) {
			$amount      = $item->get_meta( '_donorcore_donation_amount', true ) ?: $item->get_total();
			$campaign_id = $item->get_meta( '_donorcore_campaign_id', true );
			break;
		}

		if ( $campaign_id ) {
			$campaign_post = get_post( $campaign_id );
			$campaign      = $campaign_post ? $campaign_post->post_title : '';
		}

		// Replace placeholders.
		$replacements = array(
			'{receipt_number}' => 'DONORCORE-' . $order->get_id() . '-' . gmdate( 'Y' ),
			'{date}'           => $order->get_date_created()->format( 'F j, Y' ),
			'{donor_name}'     => $order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
			'{donor_email}'    => $order->get_billing_email(),
			'{donor_address}'  => $this->format_address( $order ),
			'{amount}'         => wc_price( $amount ),
			'{currency}'       => $order->get_currency(),
			'{campaign}'       => $campaign ?: 'General Donation',
			'{order_id}'       => $order->get_id(),
			'{org_name}'       => get_bloginfo( 'name' ),
			'{org_address}'    => $this->get_org_address(),
			'{site_logo}'      => $this->get_site_logo_img(),
		);

		return str_replace( array_keys( $replacements ), array_values( $replacements ), $html );
	}

	/**
	 * Format donor address.
	 *
	 * @param \WC_Order $order Order object.
	 * @return string
	 */
	private function format_address( $order ) {
		return sprintf(
			'%s<br>%s<br>%s, %s %s<br>%s',
			$order->get_billing_address_1(),
			$order->get_billing_address_2(),
			$order->get_billing_city(),
			$order->get_billing_state(),
			$order->get_billing_postcode(),
			$order->get_billing_country()
		);
	}

	/**
	 * Get site logo HTML image tag.
	 *
	 * @return string
	 */
	private function get_site_logo_img() {
		$logo_id = get_theme_mod( 'custom_logo' );
		if ( ! $logo_id ) {
			return '';
		}

		$logo_src = wp_get_attachment_image_src( $logo_id, 'full' );
		if ( ! $logo_src ) {
			return '';
		}

		// Use absolute path for Dompdf if possible, otherwise URL
		return '<img src="' . esc_url( $logo_src[0] ) . '" alt="' . esc_attr( get_bloginfo( 'name' ) ) . '" style="max-width: 200px; height: auto;" />';
	}

	/**
	 * Get organization address.
	 *
	 * @return string
	 */
	private function get_org_address() {
		// Configurable in settings.
		return wp_kses_post( get_option( 'donorcore_org_address', '' ) );
	}

	

	/**
	 * Get receipt file path.
	 *
	 * @param int $order_id Order ID.
	 * @return string
	 */
	private function get_receipt_path( $order_id ) {
		$upload_dir = wp_upload_dir();
		$dir        = $upload_dir['basedir'] . '/donor-core-receipts';
		$filename   = 'receipt-' . $order_id . '-' . time() . '.pdf';

		return trailingslashit( $dir ) . $filename;
	}

	/**
	 * Ensure receipts directory exists.
	 */
	private function ensure_directory_exists() {
		$upload_dir = wp_upload_dir();
		$dir        = $upload_dir['basedir'] . '/donor-core-receipts';

		if ( ! file_exists( $dir ) ) {
			wp_mkdir_p( $dir );
		}
	}

	/**
	 * Create .htaccess for directory protection.
	 */
	private function create_htaccess_protection() {
		$upload_dir  = wp_upload_dir();
		$dir         = $upload_dir['basedir'] . '/donor-core-receipts';
		$htaccess    = trailingslashit( $dir ) . '.htaccess';

		if ( ! file_exists( $htaccess ) ) {
			$content = "Order Deny,Allow\nDeny from all";
			file_put_contents( $htaccess, $content );
		}
	}
}
