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

namespace WarrantyCart\REST\Controllers;

use WarrantyCart\REST\BaseController;
use WP_REST_Server;

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

/**
 * OrderController class
 */
class OrderController extends BaseController {

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

	/**
	 * Register routes
	 */
	public function register_routes(): void {
		// Orders endpoints
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/orders',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_orders' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
					'args'                => $this->get_orders_args(),
				),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/orders/(?P<id>\d+)',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'get_order' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
					'args'                => array(
						'id' => array(
							'required'          => true,
							'type'              => 'integer',
							'description'       => __( 'Order ID.', 'warranty-cart' ),
							'sanitize_callback' => 'absint',
						),
					),
				),
			)
		);

		// Order PDF download endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/orders/(?P<id>\d+)/pdf',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'download_order_pdf' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
					'args'                => array(
						'id' => array(
							'required'          => true,
							'type'              => 'integer',
							'description'       => __( 'Order ID.', 'warranty-cart' ),
							'sanitize_callback' => 'absint',
						),
					),
				),
			)
		);

		// Order status update endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/orders/(?P<id>\d+)/status',
			array(
				array(
					'methods'             => WP_REST_Server::EDITABLE,
					'callback'            => array( $this, 'update_order_status' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
					'args'                => array(
						'id'     => array(
							'required'          => true,
							'type'              => 'integer',
							'description'       => __( 'Order ID.', 'warranty-cart' ),
							'sanitize_callback' => 'absint',
						),
						'status' => array(
							'required'          => true,
							'type'              => 'string',
							'enum'              => array( 'pending', 'processing', 'completed', 'cancelled', 'refunded' ),
							'description'       => __( 'New order status.', 'warranty-cart' ),
							'sanitize_callback' => 'sanitize_text_field',
						),
					),
				),
			)
		);

		// Orders CSV export endpoint
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/orders/export',
			array(
				array(
					'methods'             => WP_REST_Server::READABLE,
					'callback'            => array( $this, 'export_orders_csv' ),
					'permission_callback' => array( $this, 'check_admin_permission' ),
					'args'                => array_merge(
						$this->get_orders_args(),
						array(
							'format' => array(
								'required'          => false,
								'type'              => 'string',
								'default'           => 'csv',
								'enum'              => array( 'csv' ),
								'description'       => __( 'Export format.', 'warranty-cart' ),
								'sanitize_callback' => 'sanitize_text_field',
							),
						)
					),
				),
			)
		);
	}

	/**
	 * Get orders endpoint arguments.
	 *
	 * @return array
	 */
	private function get_orders_args(): array {
		$args = array(
			'page'     => array(
				'required'    => false,
				'type'        => 'integer',
				'default'     => 1,
				'description' => __( 'Page number.', 'warranty-cart' ),
				'minimum'     => 1,
			),
			'per_page' => array(
				'required'    => false,
				'type'        => 'integer',
				'default'     => 20,
				'description' => __( 'Items per page.', 'warranty-cart' ),
				'minimum'     => 1,
				'maximum'     => 100,
			),
			'search'   => array(
				'required'          => false,
				'type'              => 'string',
				'description'       => __( 'Search term.', 'warranty-cart' ),
				'sanitize_callback' => 'sanitize_text_field',
			),
			'status'   => array(
				'required'          => false,
				'type'              => 'string',
				'enum'              => array( 'completed', 'pending', 'cancelled' ),
				'description'       => __( 'Order status filter.', 'warranty-cart' ),
				'sanitize_callback' => 'sanitize_text_field',
			),
		);

		/**
		 * Filter orders REST API arguments.
		 *
		 * @param array $args Arguments array.
		 */
		return apply_filters( 'warranty_cart_rest_orders_args', $args );
	}

	/**
	 * Get warranty orders with pagination and filtering.
	 *
	 * @param WP_REST_Request $request REST request object.
	 *
	 * @return WP_REST_Response
	 */
	public function get_orders( WP_REST_Request $request ): WP_REST_Response {
		$page     = $request->get_param( 'page' );
		$per_page = $request->get_param( 'per_page' );
		$search   = $request->get_param( 'search' );
		$status   = $request->get_param( 'status' );

		/**
		 * Filter orders query arguments
		 *
		 * @param array           $query_args Query arguments.
		 * @param WP_REST_Request $request    Request object.
		 */
		$query_args = apply_filters(
			'warranty_cart_rest_orders_query_args',
			array(
				'limit'   => $per_page,
				'page'    => $page,
				'orderby' => 'date',
				'order'   => 'DESC',
			),
			$request
		);

		// Add status filter if provided
		if ( $status ) {
			$query_args['status'] = $status;
		}

		// Add search if provided
		if ( $search ) {
			$query_args['s'] = $search;
		}

		// Get formatted orders data from Reports class
		$response_data = warranty_cart()->reports->get_formatted_warranty_orders( $query_args, true );

		// Add currency information
		$response_data['currency']      = get_woocommerce_currency_symbol();
		$response_data['currency_code'] = get_woocommerce_currency();

		/**
		 * Filter orders REST response data
		 *
		 * @param array           $response_data Response data.
		 * @param WP_REST_Request $request       Request object.
		 */
		$response_data = apply_filters( 'warranty_cart_rest_orders_response', $response_data, $request );

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

	/**
	 * Get single order
	 *
	 * Retrieves detailed information for a specific warranty order.
	 */
	public function get_order( WP_REST_Request $request ) {
		$order_id = $request->get_param( 'id' );

		$order_data = warranty_cart()->reports->get_single_warranty_order( $order_id );

		if ( null === $order_data ) {
			return $this->error_response( __( 'Order not found or does not contain warranty products.', 'warranty-cart' ), 404 );
		}

		// Add currency information
		$order_data['currency']      = get_woocommerce_currency_symbol();
		$order_data['currency_code'] = get_woocommerce_currency();

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

	/**
	 * Download order PDF
	 *
	 * Generates and downloads a PDF warranty certificate for a specific order.
	 */
	public function download_order_pdf( WP_REST_Request $request ) {
		$order_id = $request->get_param( 'id' );

		$order = wc_get_order( $order_id );
		if ( ! $order instanceof WC_Order ) {
			return $this->error_response( __( 'Order not found.', 'warranty-cart' ), 404 );
		}

		// Check if order contains warranty products
		$warranty_data = warranty_cart()->reports->get_order_warranty_items( $order );
		if ( 0 === $warranty_data['count'] ) {
			return $this->error_response( __( 'Order does not contain warranty products.', 'warranty-cart' ), 404 );
		}

		// Generate PDF using the existing email functionality
		$email_class = new \WarrantyCart\Notifications\Emails\OrderCompletion();

		// Initialize the email class with the order (this sets $this->order)
		$email_class->trigger( $order_id );

		// Generate the PDF
		$pdf_path = $email_class->generate_warranty_pdf();

		if ( ! $pdf_path || ! file_exists( $pdf_path ) ) {
			return $this->error_response( __( 'Failed to generate PDF certificate.', 'warranty-cart' ), 500 );
		}

		// Set headers for file download
		header( 'Content-Type: application/pdf' );
		header( 'Content-Disposition: attachment; filename="' . basename( $pdf_path ) . '"' );
		header( 'Content-Length: ' . filesize( $pdf_path ) );
		header( 'Cache-Control: private, max-age=0, must-revalidate' );
		header( 'Pragma: public' );

		// Output the file using unified filesystem method
		$pdf_contents = warranty_cart()->read_file( $pdf_path );
		if ( false !== $pdf_contents ) {
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			echo $pdf_contents;
		}

		// Clean up the temporary file
		wp_delete_file( $pdf_path );

		// Exit to prevent any further output
		exit;
	}

	/**
	 * Update order status
	 *
	 * Updates the status of a warranty order.
	 */
	public function update_order_status( WP_REST_Request $request ) {
		$order_id = $request->get_param( 'id' );
		$status   = $request->get_param( 'status' );

		$order = wc_get_order( $order_id );
		if ( ! $order instanceof WC_Order ) {
			return $this->error_response( __( 'Order not found.', 'warranty-cart' ), 404 );
		}

		// Check if order contains warranty products
		$warranty_data = warranty_cart()->reports->get_order_warranty_items( $order );
		if ( 0 === $warranty_data['count'] ) {
			return $this->error_response( __( 'Order does not contain warranty products.', 'warranty-cart' ), 404 );
		}

		// Update order status
		$order->set_status( $status );
		$order->save();

		return $this->success_response(
			array(
				'message' => __( 'Order status updated successfully.', 'warranty-cart' ),
				'status'  => $status,
			)
		);
	}

	/**
	 * Export orders CSV
	 *
	 * Exports warranty orders to CSV format.
	 */
	public function export_orders_csv( WP_REST_Request $request ) {
		$page     = $request->get_param( 'page' );
		$per_page = $request->get_param( 'per_page' );
		$search   = $request->get_param( 'search' );
		$status   = $request->get_param( 'status' );

		// Get all orders (ignore pagination for export)
		$query_args = array(
			'limit'   => - 1, // Get all orders
			'orderby' => 'date',
			'order'   => 'DESC',
		);

		// Add status filter if provided
		if ( $status ) {
			$query_args['status'] = $status;
		}

		// Add search if provided
		if ( $search ) {
			$query_args['s'] = $search;
		}

		// Get formatted orders data
		$response_data = warranty_cart()->reports->get_formatted_warranty_orders( $query_args, false );

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

		// Generate CSV content
		$csv_content = $this->generate_orders_csv( $response_data['orders'] );

		// Set headers for CSV download
		$filename = 'warranty-orders-' . wp_date( 'Y-m-d-H-i-s' ) . '.csv';
		header( 'Content-Type: text/csv; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
		header( 'Cache-Control: private, max-age=0, must-revalidate' );
		header( 'Pragma: public' );

		// Output CSV content
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $csv_content;

		// Exit to prevent any further output
		exit;
	}

	/**
	 * Generate orders CSV
	 *
	 * Creates CSV content from orders data with comprehensive order information.
	 *
	 * @param array $orders Orders data.
	 *
	 * @return string CSV content.
	 */
	private function generate_orders_csv( array $orders ): string {
		$csv = array();

		// CSV headers - comprehensive order information
		$csv[] = array(
			__( 'Order ID', 'warranty-cart' ),
			__( 'Order Date', 'warranty-cart' ),
			__( 'Status', 'warranty-cart' ),
			__( 'Customer Name', 'warranty-cart' ),
			__( 'Customer Email', 'warranty-cart' ),
			__( 'Billing Phone', 'warranty-cart' ),
			__( 'Billing Address', 'warranty-cart' ),
			__( 'Billing City', 'warranty-cart' ),
			__( 'Billing Postcode', 'warranty-cart' ),
			__( 'Billing Country', 'warranty-cart' ),
			__( 'Warranty Items', 'warranty-cart' ),
			__( 'Subtotal', 'warranty-cart' ),
			__( 'Tax', 'warranty-cart' ),
			__( 'Total', 'warranty-cart' ),
			__( 'Payment Method', 'warranty-cart' ),
			__( 'Order Notes', 'warranty-cart' ),
		);

		// CSV data rows
		foreach ( $orders as $order_data ) {
			// Get full order object for additional details
			$order = wc_get_order( $order_data['id'] );
			if ( ! $order instanceof WC_Order ) {
				continue;
			}

			// Get warranty items
			$warranty_items = array();
			foreach ( $order->get_items() as $item ) {
				$product = $item->get_product();
				if ( $product && has_term( 'warranties', 'product_cat', $product->get_id() ) ) {
					$warranty_items[] = sprintf(
						'%s (x%d) - %s',
						$item->get_name(),
						$item->get_quantity(),
						wc_price( $item->get_total() )
					);
				}
			}

			$csv[] = array(
				$order->get_order_number(),
				$order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d H:i:s' ) : '',
				ucfirst( $order->get_status() ),
				$order->get_billing_first_name() . ' ' . $order->get_billing_last_name(),
				$order->get_billing_email(),
				$order->get_billing_phone(),
				$order->get_billing_address_1() . ( $order->get_billing_address_2() ? ' ' . $order->get_billing_address_2() : '' ),
				$order->get_billing_city(),
				$order->get_billing_postcode(),
				$order->get_billing_country(),
				implode( '; ', $warranty_items ),
				wc_price( $order->get_subtotal() ),
				wc_price( $order->get_total_tax() ),
				wc_price( $order->get_total() ),
				$order->get_payment_method_title(),
				$order->get_customer_note(),
			);
		}

		// Convert to CSV string with proper escaping
		$output = '';
		foreach ( $csv as $row ) {
			$escaped_row = array();
			foreach ( $row as $field ) {
				// Escape quotes and wrap in quotes
				$escaped_field = str_replace( '"', '""', (string) $field );
				$escaped_row[] = '"' . $escaped_field . '"';
			}
			$output .= implode( ',', $escaped_row ) . "\n";
		}

		return $output;
	}
}
