<?php

declare(strict_types=1);

namespace SecurWP\Modules\Settings;

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

/**
 * REST API endpoints for settings import/export.
 *
 * GET  /securwp/v1/settings/export - returns full export payload.
 * POST /securwp/v1/settings/import - accepts an export payload and returns a
 * structured success or failure contract, including rollback metadata on
 * failure.
 */
class ImportExportApi {

	private ImportExport $import_export;

	public function __construct() {
		$this->import_export = new ImportExport();
	}

	/**
	 * Register REST API routes for settings import/export.
	 */
	public function register_routes(): void {
		$ns = 'securwp/v1';

		register_rest_route( $ns, '/settings/export', [
			[
				'methods'             => \WP_REST_Server::READABLE,
				'callback'            => [ $this, 'handle_export' ],
				'permission_callback' => [ $this, 'check_permission' ],
			],
		] );

		register_rest_route( $ns, '/settings/import', [
			[
				'methods'             => \WP_REST_Server::CREATABLE,
				'callback'            => [ $this, 'handle_import' ],
				'permission_callback' => [ $this, 'check_permission' ],
			],
		] );
	}

	/**
	 * Permission check - requires the plugin management capability.
	 *
	 * @return bool
	 */
	public function check_permission(): bool {
		return \SecurWP\Includes\Capabilities::can_manage_plugin();
	}

	/**
	 * Handle GET /settings/export.
	 *
	 * @param \WP_REST_Request $request The incoming request.
	 * @return \WP_REST_Response
	 */
	public function handle_export( \WP_REST_Request $request ): \WP_REST_Response {
		$payload = $this->import_export->export();

		return new \WP_REST_Response( $payload, 200 );
	}

	/**
	 * Handle POST /settings/import.
	 *
	 * Accepts either the raw export payload { version, exported_at, settings }
	 * or the wrapped form { "settings_data": { ... } } for backward
	 * compatibility with older admin bundles. Import failures surface rollback
	 * metadata when any previously-applied changes could not be fully restored.
	 *
	 * @param \WP_REST_Request $request The incoming request.
	 * @return \WP_REST_Response
	 */
	public function handle_import( \WP_REST_Request $request ): \WP_REST_Response {
		$body = $request->get_json_params();
		$body = is_array( $body ) ? $body : [];

		if ( isset( $body['settings_data'] ) && is_array( $body['settings_data'] ) ) {
			$payload = $body['settings_data'];
		} elseif ( isset( $body['version'], $body['settings'] ) && is_array( $body['settings'] ) ) {
			$payload = $body;
		} else {
			return new \WP_REST_Response(
				[
					'success' => false,
					'message' => 'Missing or invalid import payload in request body.',
				],
				400
			);
		}

		$result = $this->import_export->import( $payload );

		if ( is_wp_error( $result ) ) {
			$error_data = is_array( $result->get_error_data() ) ? $result->get_error_data() : [];
			$status = (int) ( $error_data['status'] ?? 400 );
			return new \WP_REST_Response(
				[
					'success' => false,
					'status' => sanitize_key( (string) ( $error_data['operation_status'] ?? 'failed' ) ),
					'message' => $result->get_error_message(),
					'rollback_failed' => ! empty( $error_data['rollback_failed'] ),
					'rollback_failures' => array_values( array_map( 'sanitize_text_field', is_array( $error_data['rollback_failures'] ?? null ) ? $error_data['rollback_failures'] : [] ) ),
					'applied_columns' => array_values( array_map( 'sanitize_text_field', is_array( $error_data['applied_columns'] ?? null ) ? $error_data['applied_columns'] : [] ) ),
				],
				$status
			);
		}

		return new \WP_REST_Response(
			[
				'success' => ! empty( $result['ok'] ),
				'status' => sanitize_key( (string) ( $result['status'] ?? 'success' ) ),
				'message' => 'Settings imported successfully.',
				'result' => $result,
			],
			200
		);
	}
}
