<?php
/**
 * Tour export and import REST controller (JSON).
 *
 * @package Vist360
 */

namespace Vist360\Rest;

defined( 'ABSPATH' ) || exit;

use Vist360\Domain\TourPostType;

/**
 * Exports a tour as portable JSON and imports it back with image sideloading.
 */
class ExportImportController {

	/**
	 * Hook registrations.
	 */
	public function register_hooks() {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
	}

	/**
	 * Register REST routes.
	 */
	public function register_routes() {
		register_rest_route(
			AnalyticsController::REST_NAMESPACE,
			'/tours/(?P<id>\d+)/export',
			array(
				'methods'             => \WP_REST_Server::READABLE,
				'callback'            => array( $this, 'export_tour' ),
				'permission_callback' => function ( $request ) {
					return current_user_can( 'edit_post', (int) $request['id'] );
				},
				'args'                => array(
					'id' => array(
						'type'     => 'integer',
						'required' => true,
					),
				),
			)
		);

		register_rest_route(
			AnalyticsController::REST_NAMESPACE,
			'/tours/import',
			array(
				'methods'             => \WP_REST_Server::CREATABLE,
				'callback'            => array( $this, 'import_tour' ),
				'permission_callback' => function () {
					return current_user_can( 'edit_posts' ) && current_user_can( 'upload_files' );
				},
			)
		);
	}

	/**
	 * Export a tour as a portable JSON structure.
	 *
	 * @param \WP_REST_Request $request Request object.
	 * @return \WP_REST_Response|\WP_Error
	 */
	public function export_tour( $request ) {
		$post = get_post( (int) $request['id'] );

		if ( ! $post || TourPostType::POST_TYPE !== $post->post_type ) {
			return new \WP_Error(
				'vist360_not_found',
				__( 'Tour not found.', 'vistour-virtual-tour-builder' ),
				array( 'status' => 404 )
			);
		}

		$scenes = (array) get_post_meta( $post->ID, '_vist360_scenes', true );

		foreach ( $scenes as &$scene ) {
			$scene['image_url'] = ! empty( $scene['image_id'] )
				? (string) wp_get_attachment_image_url( $scene['image_id'], 'full' )
				: '';
			unset( $scene['image_id'] );
		}
		unset( $scene );

		return rest_ensure_response(
			array(
				'format'  => 'vist360-tour',
				'version' => 1,
				'title'   => $post->post_title,
				'scenes'  => $scenes,
				'viewer'  => (array) get_post_meta( $post->ID, '_vist360_viewer', true ),
			)
		);
	}

	/**
	 * Import a tour from exported JSON, sideloading scene images.
	 *
	 * @param \WP_REST_Request $request Request object.
	 * @return \WP_REST_Response|\WP_Error
	 */
	public function import_tour( $request ) {
		$data = $request->get_json_params();

		if ( empty( $data ) || ! is_array( $data ) || 'vist360-tour' !== ( $data['format'] ?? '' ) ) {
			return new \WP_Error(
				'vist360_invalid_import',
				__( 'Invalid tour file. Expected a JSON export from this plugin.', 'vistour-virtual-tour-builder' ),
				array( 'status' => 400 )
			);
		}

		$tour_id = wp_insert_post(
			array(
				'post_type'   => TourPostType::POST_TYPE,
				'post_title'  => sanitize_text_field( $data['title'] ?? __( 'Imported Tour', 'vistour-virtual-tour-builder' ) ),
				'post_status' => 'draft',
			),
			true
		);

		if ( is_wp_error( $tour_id ) ) {
			return $tour_id;
		}

		require_once ABSPATH . 'wp-admin/includes/media.php';
		require_once ABSPATH . 'wp-admin/includes/file.php';
		require_once ABSPATH . 'wp-admin/includes/image.php';

		$scenes = array();

		foreach ( (array) ( $data['scenes'] ?? array() ) as $scene ) {
			if ( ! is_array( $scene ) ) {
				continue;
			}

			$image_id  = 0;
			$image_url = esc_url_raw( $scene['image_url'] ?? '' );

			if ( $image_url ) {
				$sideloaded = media_sideload_image( $image_url, $tour_id, null, 'id' );
				if ( ! is_wp_error( $sideloaded ) ) {
					$image_id = (int) $sideloaded;
				}
			}

			unset( $scene['image_url'] );
			$scene['image_id'] = $image_id;
			$scenes[]          = $scene;
		}

		$post_type = new TourPostType();
		update_post_meta( $tour_id, '_vist360_scenes', $post_type->sanitize_scenes( $scenes ) );
		update_post_meta( $tour_id, '_vist360_viewer', $post_type->sanitize_viewer( (array) ( $data['viewer'] ?? array() ) ) );

		return rest_ensure_response(
			array(
				'id'    => $tour_id,
				'title' => get_the_title( $tour_id ),
			)
		);
	}
}
