<?php
/**
 * Export class.
 *
 * @package     EDD\Pro\Invoices\Admin
 * @copyright   Copyright (c) 2025, Sandhills Development, LLC
 * @license     https://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       3.5.0
 */

namespace EDD\Pro\Invoices\Admin;

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

use EDD\Admin\Exports\Exporters\Exporter;
use EDD\Pro\Invoices\XML\Document;

/**
 * Export class.
 *
 * @since 3.5.0
 */
class Export extends Exporter {

	/**
	 * The file type, typically .csv
	 *
	 * @since 3.5.0
	 * @var string
	 */
	public $filetype = 'zip';

	/**
	 * The ZipArchive object.
	 *
	 * @since 3.5.0
	 * @var \ZipArchive
	 */
	private $zip;

	/**
	 * The year to export.
	 *
	 * @since 3.5.0
	 * @var int
	 */
	private $year;

	/**
	 * The month to export.
	 *
	 * @since 3.5.0
	 * @var int
	 */
	private $month;

	/**
	 * The status to export.
	 *
	 * @since 3.5.0
	 * @var string
	 */
	private $status = false;

	/**
	 * Process a step.
	 *
	 * @since 3.5.0
	 * @return bool
	 */
	public function process_step() {
		if ( ! $this->can_export() ) {
			wp_die( __( 'You do not have permission to export invoices.', 'easy-digital-downloads' ) );
		}

		$data = $this->get_data();
		if ( ! $data ) {
			return false;
		}

		$this->check_zip();
		foreach ( $data as $order ) {
			$xml       = new Document( edd_get_order( $order ) );
			$file_path = $xml->generate();

			if ( $file_path ) {
				$this->zip->addFile( $file_path, basename( $file_path ) );
			}
		}

		return true;
	}

	/**
	 * Export the file.
	 *
	 * @since 3.5.0
	 */
	public function export() {
		if ( ! $this->can_export() ) {
			wp_die( esc_html__( 'You do not have permission to export invoices.', 'easy-digital-downloads' ) );
		}

		$this->get_file();

		edd_set_time_limit();
		nocache_headers();
		header( 'Content-Type: application/zip' );
		header( 'Content-Disposition: attachment; filename="' . $this->get_final_filename() . '"' );
		header( 'Content-Transfer-Encoding: binary' );
		header( 'Content-Length: ' . filesize( $this->file ) );

		readfile( $this->file );

		$this->file_system->delete( $this->file );
		$transient = $this->get_transient();
		$transient->delete();

		edd_die();
	}

	/**
	 * Get the data to export.
	 *
	 * @since 3.5.0
	 * @return array
	 */
	public function get_data(): array {
		$args           = $this->get_order_args();
		$args['number'] = $this->per_step;
		$args['offset'] = $this->per_step * ( $this->step - 1 );

		return edd_get_orders( $args );
	}

	/**
	 * Return the calculated completion percentage
	 *
	 * @since 3.5.0
	 * @return int
	 */
	protected function get_total(): int {
		return edd_count_orders( $this->get_order_args() );
	}

	/**
	 * Set the properties specific to the export.
	 *
	 * @since 3.5.0
	 * @param array $request The Form Data passed into the batch processing.
	 */
	public function set_properties( $request ): void {
		if ( isset( $request['year'] ) ) {
			$this->year = sanitize_text_field( $request['year'] );
		}
		if ( isset( $request['month'] ) ) {
			$this->month = sanitize_text_field( $request['month'] );
		}
		if ( isset( $request['status'] ) && 'all' !== $request['status'] ) {
			$this->status = sanitize_text_field( $request['status'] );
		}
	}

	/**
	 * Retrieve the file data is written to
	 *
	 * @since 3.5.0
	 * @return string
	 */
	protected function check_zip() {

		if ( $this->zip ) {
			return;
		}

		$this->maybe_set_up_file();

		$this->zip = new \ZipArchive();
		if ( file_exists( $this->file ) ) {
			$this->zip->open( $this->file );
		} else {
			$this->zip->open( $this->file, \ZipArchive::CREATE );
		}
	}

	/**
	 * Get the export type.
	 *
	 * @since 3.5.0
	 * @return string
	 */
	protected function get_export_type(): string {
		return 'invoices_xml';
	}

	/**
	 * Get the data headers.
	 *
	 * @since 3.5.0
	 * @return array
	 */
	protected function get_data_headers(): array {
		return array();
	}

	/**
	 * Gets the parameters for getting orders from the database.
	 *
	 * @since 3.5.0
	 * @return array
	 */
	private function get_order_args() {
		$args = array(
			'type' => 'sale',
		);
		if ( $this->status ) {
			$args['status'] = $this->status;
		} else {
			$args['status__in'] = edd_invoices_get_invoiceable_order_statuses();
		}
		$date_query = $this->get_date_query();
		if ( $date_query ) {
			$args['date_query'] = $date_query;
		}

		return $args;
	}

	/**
	 * Gets the date query for fetching orders.
	 *
	 * @since 3.5.0
	 * @return false|array
	 */
	protected function get_date_query() {
		if ( empty( $this->year ) || empty( $this->month ) ) {
			return false;
		}

		return array(
			array(
				'after'     => "{$this->year}-{$this->month}-1",
				'before'    => $this->year . '-' . $this->month . '-' . cal_days_in_month( CAL_GREGORIAN, $this->month, $this->year ),
				'inclusive' => true,
			),
		);
	}
}
