<?php
/**
 * GGM Commerce Taxonomy CSV Exporter
 *
 * Handles CSV export functionality for categories and tags
 *
 * @package GGM_Commerce
 * @since 1.0.0
 */

// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class GGM_Commerce_Taxonomy_CSV_Exporter
 *
 * Exports categories and tags to CSV format
 */
class GGM_Commerce_Taxonomy_CSV_Exporter {

	/**
	 * Export type: 'categories' or 'tags'
	 *
	 * @var string
	 */
	private $export_type;

	/**
	 * Constructor
	 *
	 * @param string $export_type Export type ('categories' or 'tags').
	 */
	public function __construct( $export_type = 'categories' ) {
		$this->export_type = $export_type;
	}

	/**
	 * Export data to CSV
	 *
	 * @param array $options Export options.
	 * @return array|WP_Error Result with file path or error.
	 */
	public function export( $options = array() ) {
		$defaults = array(
			'status' => '', // Empty means all statuses.
		);

		$options = wp_parse_args( $options, $defaults );

		// Get data to export.
		if ( 'categories' === $this->export_type ) {
			$data = $this->get_categories( $options );
			$headers = $this->get_category_headers();
		} else {
			$data = $this->get_tags( $options );
			$headers = $this->get_tag_headers();
		}

		if ( empty( $data ) ) {
			return new WP_Error(
				'no_data',
				sprintf(
					/* translators: %s: export type (categories or tags) */
					__( 'No %s found to export', 'ggm-commerce' ),
					$this->export_type
				)
			);
		}

		// Build CSV rows.
		$rows = array();
		foreach ( $data as $item ) {
			if ( 'categories' === $this->export_type ) {
				$rows[] = $this->build_category_row( $item );
			} else {
				$rows[] = $this->build_tag_row( $item );
			}
		}

		// Generate CSV file.
		$filename = 'ggm-' . $this->export_type . '-export-' . gmdate( 'Y-m-d-His' ) . '.csv';
		$filepath = $this->get_export_directory() . $filename;

		$this->write_csv( $filepath, $headers, $rows );

		return array(
			'success'  => true,
			'file'     => $filepath,
			'filename' => $filename,
			'count'    => count( $rows ),
			'type'     => $this->export_type,
		);
	}

	/**
	 * Get category headers
	 *
	 * @return array CSV headers for categories.
	 */
	private function get_category_headers() {
		return array(
			'name',
			'slug',
			'description',
			'parent_slug',
			'display_order',
			'image_url',
			'status',
		);
	}

	/**
	 * Get tag headers
	 *
	 * @return array CSV headers for tags.
	 */
	private function get_tag_headers() {
		return array(
			'name',
			'slug',
			'description',
			'status',
		);
	}

	/**
	 * Get categories for export
	 *
	 * @param array $options Filter options.
	 * @return array Categories.
	 */
	private function get_categories( $options ) {
		global $wpdb;

		$where = array( '1=1' );

		if ( ! empty( $options['status'] ) ) {
			$where[] = $wpdb->prepare( 'c.status = %s', $options['status'] );
		}

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return $wpdb->get_results(
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			"SELECT c.*, p.slug as parent_slug
			 FROM {$wpdb->prefix}ggmc_categories c
			 LEFT JOIN {$wpdb->prefix}ggmc_categories p ON c.parent_id = p.id
			 WHERE " . implode( ' AND ', $where ) . '
			 ORDER BY c.parent_id ASC, c.display_order ASC, c.name ASC'
		);
	}

	/**
	 * Get tags for export
	 *
	 * @param array $options Filter options.
	 * @return array Tags.
	 */
	private function get_tags( $options ) {
		global $wpdb;

		$where = array( '1=1' );

		if ( ! empty( $options['status'] ) ) {
			$where[] = $wpdb->prepare( 'status = %s', $options['status'] );
		}

		// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
		return $wpdb->get_results(
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
			"SELECT * FROM {$wpdb->prefix}ggmc_tags
			 WHERE " . implode( ' AND ', $where ) . '
			 ORDER BY name ASC'
		);
	}

	/**
	 * Build a category row for CSV export
	 *
	 * @param object $category Category object.
	 * @return array Row data.
	 */
	private function build_category_row( $category ) {
		return array(
			'name'          => $category->name,
			'slug'          => $category->slug,
			'description'   => $category->description ?? '',
			'parent_slug'   => $category->parent_slug ?? '',
			'display_order' => $category->display_order ?? 0,
			'image_url'     => $this->get_image_url( $category->image_id ?? 0 ),
			'status'        => $category->status ?? 'active',
		);
	}

	/**
	 * Build a tag row for CSV export
	 *
	 * @param object $tag Tag object.
	 * @return array Row data.
	 */
	private function build_tag_row( $tag ) {
		return array(
			'name'        => $tag->name,
			'slug'        => $tag->slug,
			'description' => $tag->description ?? '',
			'status'      => $tag->status ?? 'active',
		);
	}

	/**
	 * Get image URL from attachment ID
	 *
	 * @param int $image_id Attachment ID.
	 * @return string Image URL or empty string.
	 */
	private function get_image_url( $image_id ) {
		if ( empty( $image_id ) ) {
			return '';
		}

		$url = wp_get_attachment_url( $image_id );
		return $url ? $url : '';
	}

	/**
	 * Get export directory path
	 *
	 * @return string Directory path.
	 */
	private function get_export_directory() {
		$upload_dir = wp_upload_dir();
		$export_dir = $upload_dir['basedir'] . '/ggm-commerce-exports/';

		if ( ! file_exists( $export_dir ) ) {
			wp_mkdir_p( $export_dir );

			// Add index.php to prevent directory listing.
			file_put_contents( $export_dir . 'index.php', '<?php // Silence is golden' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents

			// Add .htaccess to protect files.
			file_put_contents( $export_dir . '.htaccess', "deny from all\n" ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_file_put_contents
		}

		return $export_dir;
	}

	/**
	 * Write CSV file
	 *
	 * @param string $filepath File path.
	 * @param array  $headers CSV headers.
	 * @param array  $rows Data rows.
	 */
	private function write_csv( $filepath, $headers, $rows ) {
		$handle = fopen( $filepath, 'w' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen

		// Add BOM for Excel UTF-8 compatibility.
		fwrite( $handle, "\xEF\xBB\xBF" ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite

		// Write headers.
		fputcsv( $handle, $headers );

		// Write rows.
		foreach ( $rows as $row ) {
			// Ensure row values are in header order.
			$ordered_row = array();
			foreach ( $headers as $header ) {
				$ordered_row[] = isset( $row[ $header ] ) ? $row[ $header ] : '';
			}
			fputcsv( $handle, $ordered_row );
		}

		fclose( $handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
	}

	/**
	 * Generate a template CSV for import reference
	 *
	 * @return array|WP_Error Result with file path or error.
	 */
	public function generate_template() {
		$headers = 'categories' === $this->export_type
			? $this->get_category_headers()
			: $this->get_tag_headers();

		$example_row = 'categories' === $this->export_type
			? array(
				'name'          => 'Example Category',
				'slug'          => 'example-category',
				'description'   => 'This is an example category description',
				'parent_slug'   => '',
				'display_order' => '0',
				'image_url'     => 'https://example.com/image.jpg',
				'status'        => 'active',
			)
			: array(
				'name'        => 'Example Tag',
				'slug'        => 'example-tag',
				'description' => 'This is an example tag description',
				'status'      => 'active',
			);

		$filename = 'ggm-' . $this->export_type . '-template.csv';
		$filepath = $this->get_export_directory() . $filename;

		$this->write_csv( $filepath, $headers, array( $example_row ) );

		return array(
			'success'  => true,
			'file'     => $filepath,
			'filename' => $filename,
			'type'     => $this->export_type,
		);
	}
}
