<?php

namespace WPDesk\FakturyKSEF\Controller;

use WPDesk\FakturyKSEF\Services\XMLGeneratorService;
use WPDeskKSEFVendor\WPDesk\PluginBuilder\Plugin\Hookable;

class DownloadXMLController implements Hookable {

	public const ACTION                = 'fiksef_download_xml';
	public const NONCE_ACTION_DOWNLOAD = 'ksef_download_xml_action';
	public const NONCE_FIELD           = '_ksef_nonce';

	private XMLGeneratorService $xml_generator;

	public function __construct( XMLGeneratorService $xml_generator ) {
		$this->xml_generator = $xml_generator;
	}

	public function hooks() {
		add_action( 'wp_ajax_' . self::ACTION, [ $this, 'handle_download_xml' ] );
	}

	public function handle_download_xml() {
		check_ajax_referer( self::NONCE_ACTION_DOWNLOAD, self::NONCE_FIELD );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Permission denied.', 'ksef-for-flexible-invoices' ) );
		}

		$document_id = isset( $_GET['document_id'] ) ? absint( $_GET['document_id'] ) : 0;

		if ( ! $document_id ) {
			wp_die( esc_html__( 'Missing document id.', 'ksef-for-flexible-invoices' ) );
		}

		try {
			$xml_content = $this->xml_generator->generate_for_document_id_without_validation( $document_id );

			$filename = apply_filters( 'fiksef_download_xml_filename', 'ksef_xml' . $document_id . '.xml' );

			$this->set_headers( $filename, $xml_content );

			if ( ob_get_level() ) {
				ob_end_clean();
			}

			echo $xml_content; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			exit;

		} catch ( \Exception $e ) {
			// translators: 1. error message
			wp_die( esc_html( sprintf( __( 'Failed to generate XML: %s', 'ksef-for-flexible-invoices' ), $e->getMessage() ) ) );
		}
	}

	private function set_headers( string $filename, string $xml_content ): void {
		header( 'Content-Description: File Transfer' );
		header( 'Content-Type: text/xml; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename=' . $filename );
		header( 'Content-Transfer-Encoding: binary' );
		header( 'Expires: 0' );
		header( 'Cache-Control: must-revalidate' );
		header( 'Pragma: public' );
		header( 'Content-Length: ' . strlen( $xml_content ) );
	}
}
