<?php
/**
 * Tool Controller for Warranty Cart Admin REST API
 *
 * Handles tool-related REST API operations.
 *
 * @package WarrantyCart
 */

namespace WarrantyCart\REST\Controllers;

use WarrantyCart\REST\BaseController;
use WC_Order;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * ToolController class
 */
class ToolController extends BaseController {

	/**
	 * Constructor
	 */
	public function __construct() {
		$this->rest_base = 'admin';
	}

	/**
	 * Register routes
	 */
	public function register_routes(): void {
		// Tools endpoints
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/tools/import',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'import_csv' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
					'args'                => $this->get_import_args(),
				),
			)
		);

		// Sample CSV download endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/tools/sample-csv',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'download_sample_csv' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
				),
			)
		);

		// Clear cache endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/tools/clear-cache',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'clear_cache' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
				),
			)
		);

		// System status endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/tools/system-status',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_system_status' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
				),
			)
		);

		// Database repair endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/tools/database-repair',
			array(
				array(
					'methods'             => WP_REST_Server::CREATABLE,
					'callback'            => array( $this, 'repair_database' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
				),
			)
		);

		// Export data endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/tools/export-data',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'export_warranty_data' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
				),
			)
		);
	}

	/**
	 * Get import endpoint arguments.
	 *
	 * @return array
	 */
	private function get_import_args(): array {
		return array(
			'csv_file' => array(
				'required'          => true,
				'description'       => __( 'CSV file to import.', 'warranty-cart' ),
				'type'              => 'file',
				'validate_callback' => array( $this, 'validate_csv_file' ),
			),
		);
	}

	/**
	 * Import CSV file and create warranty products.
	 *
	 * @param WP_REST_Request $request REST request object.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function import_csv( WP_REST_Request $request ) {
		$files = $request->get_file_params();

		if ( empty( $files['csv_file'] ) ) {
			return $this->error_response( __( 'No file uploaded.', 'warranty-cart' ), 400 );
		}

		$file = $files['csv_file'];

		// Validate file
		if ( UPLOAD_ERR_OK !== $file['error'] ) {
			return $this->error_response( __( 'File upload error.', 'warranty-cart' ), 400 );
		}

		// Check if product import functionality is available
		if ( ! isset( warranty_cart()->product_import ) ) {
			return $this->error_response( __( 'Product import functionality not available.', 'warranty-cart' ), 500 );
		}

		// Create temporary file using unified filesystem methods
		$file_contents = warranty_cart()->read_file( $file['tmp_name'] );
		if ( false === $file_contents ) {
			return $this->error_response( __( 'Failed to read uploaded file.', 'warranty-cart' ), 500 );
		}

		$temp_file = wp_tempnam();
		if ( ! warranty_cart()->write_file( $temp_file, $file_contents ) ) {
			return $this->error_response( __( 'Failed to process uploaded file.', 'warranty-cart' ), 500 );
		}

		// Process the CSV import
		try {
			$results = warranty_cart()->product_import->process_csv_import( $temp_file, 'warranty' );

			// Format results for API response
			$formatted_results = array(
				'total'      => $results,
				'successful' => $results,
				'failed'     => 0,
				'errors'     => array(),
				'message'    => sprintf(
				/* translators: %d: number of imported products */
					__( 'Successfully imported %d warranty products.', 'warranty-cart' ),
					$results
				),
			);
		} catch ( \Throwable $e ) {
			wp_delete_file( $temp_file );

			return $this->error_response( $e->getMessage(), 500 );
		}

		// Clean up temp file
		wp_delete_file( $temp_file );

		return $this->success_response( $formatted_results );
	}

	/**
	 * Validate CSV file before import.
	 *
	 * @param array $file File data from upload.
	 *
	 * @return bool True if file is valid, false otherwise.
	 */
	public function validate_csv_file( $file ): bool {
		if ( empty( $file['name'] ) ) {
			return false;
		}

		// Check file extension
		$extension = strtolower( pathinfo( $file['name'], PATHINFO_EXTENSION ) );
		if ( 'csv' !== $extension ) {
			return false;
		}

		// Check file size (5MB limit)
		if ( 5 * 1024 * 1024 < $file['size'] ) {
			return false;
		}

		return true;
	}

	/**
	 * Download sample CSV file for import.
	 *
	 * @param WP_REST_Request $request REST request object.
	 *
	 * @return void
	 */
	public function download_sample_csv( WP_REST_Request $request ): void {
		// Set headers for CSV download
		header( 'Content-Type: text/csv; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename="warranty-products-sample.csv"' );
		header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );

		// Create sample CSV content
		$csv_content  = "name,description,price,warranty_type,duration,duration_unit,coverage_details,associated_warranty,service_priority\n";
		$csv_content .= '"Extended Warranty - 2 Years","Extended warranty coverage for 2 years","49.99","main_warranty","2","years","Comprehensive coverage including parts and labor","",""' . "\n";
		$csv_content .= '"Premium Protection Plan","Premium protection with priority support","79.99","main_warranty","1","years","Premium coverage with 24/7 support","",""' . "\n";
		$csv_content .= '"Basic Warranty - 1 Year","Standard warranty coverage","29.99","main_warranty","1","years","Basic coverage for manufacturing defects","",""' . "\n";
		$csv_content .= '"Additional Support Service","Priority technical support","19.99","additional_service","1","years","24/7 technical support","Extended Warranty - 2 Years","recommended"' . "\n";

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

	/**
	 * Clear all plugin caches and transients.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function clear_cache() {
		try {
			global $wpdb;

			// Clear plugin-specific transients
			$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_warranty_%'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk cleanup operation requires direct query
			$wpdb->query( "DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_timeout_warranty_%'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Bulk cleanup operation requires direct query

			// Clear specific transients
			delete_transient( 'warranty_sales_data' );
			delete_transient( 'warranty_dashboard_data' );
			delete_transient( 'warranty_reports_data' );
			delete_transient( 'warranty_product_count' );
			delete_transient( 'warranty_order_count' );

			// Clear WooCommerce product cache for warranty products
			if ( function_exists( 'wc_delete_product_transients' ) ) {
				$warranty_products = warranty_cart()->reports->get_warranty_product_ids();
				foreach ( $warranty_products as $product_id ) {
					wc_delete_product_transients( $product_id );
				}
			}

			// Clear object cache if available
			if ( function_exists( 'wp_cache_flush' ) ) {
				wp_cache_flush();
			}

			// Clear opcode cache if available
			if ( function_exists( 'opcache_reset' ) ) {
				opcache_reset();
			}

			return $this->success_response(
				array(
					'message'       => __( 'Cache cleared successfully.', 'warranty-cart' ),
					'cleared_items' => array(
						'transients'   => true,
						'object_cache' => function_exists( 'wp_cache_flush' ),
						'opcode_cache' => function_exists( 'opcache_reset' ),
					),
				)
			);
		} catch ( \Throwable $e ) {
			return $this->error_response( $e->getMessage(), 500 );
		}
	}

	/**
	 * Get system status information.
	 *
	 * @param WP_REST_Request $request REST request object.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function get_system_status( WP_REST_Request $request ) {
		global $wpdb;

		$status = array(
			'php_version'         => PHP_VERSION,
			'wordpress_version'   => get_bloginfo( 'version' ),
			'woocommerce_version' => function_exists( 'WC' ) ? WC()->version : 'Not installed',
			'mysql_version'       => $wpdb->db_version(),
			'memory_limit'        => ini_get( 'memory_limit' ),
			'max_execution_time'  => ini_get( 'max_execution_time' ),
			'upload_max_filesize' => ini_get( 'upload_max_filesize' ),
			'post_max_size'       => ini_get( 'post_max_size' ),
			'wp_debug'            => defined( 'WP_DEBUG' ) && WP_DEBUG ? 'Enabled' : 'Disabled',
			'wp_cache'            => defined( 'WP_CACHE' ) && WP_CACHE ? 'Enabled' : 'Disabled',
			'opcache_enabled'     => function_exists( 'opcache_get_status' ) && opcache_get_status() ? 'Enabled' : 'Disabled',
			'warranty_products'   => count( warranty_cart()->reports->get_warranty_product_ids() ),
			'warranty_orders'     => warranty_cart()->reports->get_total_warranty_orders(),
		);

		// Check requirements
		$requirements = array(
			'php_version_ok'     => version_compare( PHP_VERSION, '7.4', '>=' ),
			'wordpress_ok'       => version_compare( get_bloginfo( 'version' ), '5.0', '>=' ),
			'woocommerce_ok'     => version_compare( WC()->version, '5.0', '>=' ),
			'memory_ok'          => wp_convert_hr_to_bytes( ini_get( 'memory_limit' ) ) >= 128 * 1024 * 1024, // 128MB
			'mysql_ok'           => function_exists( 'WC' ) && version_compare( $wpdb->db_version(), '5.6', '>=' ),
			'upload_size_ok'     => wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) ) >= 5 * 1024 * 1024, // 5MB
			'execution_time_ok'  => ini_get( 'max_execution_time' ) >= 30 || ini_get( 'max_execution_time' ) === 0,
			'https_enabled'      => is_ssl(),
			'permalinks_enabled' => get_option( 'permalink_structure' ) !== '',
		);

		return $this->success_response(
			array(
				'status'       => $status,
				'requirements' => $requirements,
			)
		);
	}

	/**
	 * Repair database tables.
	 *
	 * @param WP_REST_Request $request REST request object.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function repair_database( WP_REST_Request $request ) {
		try {
			global $wpdb;

			// Get all tables
			$tables = $wpdb->get_col( 'SHOW TABLES' ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Administrative operation requires direct database access

			$repaired_tables = array();
			$errors          = array();

			foreach ( $tables as $table ) {
				// Only repair essential WooCommerce and WordPress core tables that might be related to warranties
				if ( strpos( $table, $wpdb->prefix . 'posts' ) === 0 ||
					strpos( $table, $wpdb->prefix . 'postmeta' ) === 0 ||
					strpos( $table, $wpdb->prefix . 'woocommerce_' ) === 0 ||
					strpos( $table, $wpdb->prefix . 'wc_' ) === 0 ) {
					// Check if table exists and is accessible before repairing
					$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Administrative operation requires direct database access
					if ( $table_exists ) {
						$result = $wpdb->query( $wpdb->prepare( 'REPAIR TABLE %s', $table ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Database maintenance operation requires direct access
						if ( false !== $result ) {
							$repaired_tables[] = $table;
						} else {
							$errors[] = "Failed to repair table: {$table}";
						}
					}
				}
			}

			// Optimize tables
			$optimized_tables = array();
			foreach ( $repaired_tables as $table ) {
				$result = $wpdb->query( $wpdb->prepare( 'OPTIMIZE TABLE %s', $table ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching -- Database maintenance operation requires direct access
				if ( false !== $result ) {
					$optimized_tables[] = $table;
				}
			}

			return $this->success_response(
				array(
					'repaired_tables'  => $repaired_tables,
					'optimized_tables' => $optimized_tables,
					'errors'           => $errors,
					'message'          => sprintf(
					/* translators: 1: number of repaired tables, 2: number of optimized tables */
						__( 'Repaired %1$d tables and optimized %2$d tables.', 'warranty-cart' ),
						count( $repaired_tables ),
						count( $optimized_tables )
					),
				)
			);
		} catch ( \Throwable $e ) {
			return $this->error_response( $e->getMessage(), 500 );
		}
	}

	/**
	 * Export warranty data to CSV format.
	 *
	 * @param WP_REST_Request $request REST request object.
	 *
	 * @return WP_REST_Response|WP_Error
	 */
	public function export_warranty_data( WP_REST_Request $request ) {
		try {
			// Check if there are any warranty products
			$warranty_products = warranty_cart()->reports->get_warranty_product_ids();
			if ( empty( $warranty_products ) ) {
				return $this->error_response( __( 'No warranty products found to export.', 'warranty-cart' ), 404 );
			}

			// Check if there are any warranty orders
			$orders = wc_get_orders(
				array(
					'limit'   => 1,
					'orderby' => 'date',
					'order'   => 'DESC',
				)
			);

			$has_warranty_orders = false;
			foreach ( $orders as $order ) {
				if ( $order instanceof WC_Order ) {
					$warranty_data = warranty_cart()->reports->get_order_warranty_items( $order );
					if ( ! empty( $warranty_data['items'] ) ) {
						$has_warranty_orders = true;
						break;
					}
				}
			}

			if ( ! $has_warranty_orders ) {
				return $this->error_response( __( 'No warranty orders found to export.', 'warranty-cart' ), 404 );
			}

			// Set headers for CSV download
			header( 'Content-Type: text/csv; charset=utf-8' );
			header( 'Content-Disposition: attachment; filename="warranty-data-' . wp_date( 'Y-m-d' ) . '.csv"' );
			header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );

			// CSV headers
			$csv_headers = array(
				'Order ID',
				'Customer Name',
				'Email',
				'Product Name',
				'Quantity',
				'Price',
				'Order Date',
				'Status',
				'Warranty Type',
				'Duration',
				'Duration Unit',
			);

			// Output CSV headers with proper escaping
			$escaped_headers = array_map( array( $this, 'escape_csv_field' ), $csv_headers );
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo '"' . implode( '","', $escaped_headers ) . "\"\n";

			// Get orders containing warranty products
			$orders = wc_get_orders(
				array(
					'limit'   => - 1,
					'orderby' => 'date',
					'order'   => 'DESC',
				)
			);

			foreach ( $orders as $order ) {
				if ( ! $order instanceof WC_Order ) {
					continue;
				}

				$warranty_data = warranty_cart()->reports->get_order_warranty_items( $order );

				if ( empty( $warranty_data['items'] ) ) {
					continue;
				}

				foreach ( $warranty_data['items'] as $item ) {
					$product = wc_get_product( $item['product_id'] );
					if ( ! $product ) {
						continue;
					}

					$row = array(
						$order->get_id(),
						$order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
						$order->get_billing_email(),
						$item['product_name'],
						$item['quantity'],
						$item['total'],
						$order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d H:i:s' ) : '',
						$order->get_status(),
						$product->get_meta( '_warranty_cart_product_type', true ) ? $product->get_meta( '_warranty_cart_product_type', true ) : 'main_warranty',
						$product->get_meta( '_warranty_cart_duration', true ) ? $product->get_meta( '_warranty_cart_duration', true ) : '',
						$product->get_meta( '_warranty_cart_duration_unit', true ) ? $product->get_meta( '_warranty_cart_duration_unit', true ) : '',
					);

					$escaped_row = array_map( array( $this, 'escape_csv_field' ), $row );
					// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					echo '"' . implode( '","', $escaped_row ) . "\"\n";
				}
			}

			exit;
		} catch ( \Throwable $e ) {
			// If headers already sent, we can't change response
			if ( ! headers_sent() ) {
				header( 'Content-Type: application/json' );
				echo wp_json_encode(
					array(
						'success' => false,
						'message' => $e->getMessage(),
					)
				);
			}
		}
	}

	/**
	 * Escape a field for CSV output.
	 *
	 * @param mixed $field Field value to escape.
	 *
	 * @return string
	 */
	private function escape_csv_field( $field ): string {
		// Convert to string and escape quotes by doubling them
		$escaped = str_replace( '"', '""', (string) $field );

		// If field contains comma, newline, or quote, wrap in quotes
		if ( strpos( $escaped, ',' ) !== false ||
			strpos( $escaped, "\n" ) !== false ||
			strpos( $escaped, "\r" ) !== false ||
			strpos( $escaped, '"' ) !== false ) {
			return '"' . $escaped . '"';
		}

		return $escaped;
	}
}
