<?php

namespace HulkPlugins\ElementorPro\Forms\AdvancedFields\Routes;

use HulkPlugins\ElementorPro\Forms\AdvancedFields\Utils\Filesystem;
use HulkPlugins\ElementorPro\Forms\AdvancedFields\Utils\FileUtil;
use WP_Error;
use WP_HTTP_Response;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;
use const HulkPlugins\ElementorPro\Forms\AdvancedFields\GROUP;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

class DropzoneRoute {

	public function __construct() {

		register_rest_route(
			GROUP . '/v1',
			'/dropzone/upload',
			[
				'methods'             => WP_REST_Server::CREATABLE,
				'callback'            => [ $this, 'upload' ],
				'permission_callback' => '__return_true',
			]
		);
	}

	/**
	 * @param WP_REST_Request $request
	 *
	 * @return WP_Error|WP_HTTP_Response|WP_REST_Response
	 */
	public function upload( WP_REST_Request $request ) {
		$params = $request->get_params();
		$files = $request->get_file_params();

		// Get file data from the request
		$file_name = sanitize_text_field( $params['file_name'] );
		$uniq_id = sanitize_text_field( $params['uniq_id'] );
		$chunk_index = (int) $params['chunk_index'];
		$total_chunks = (int) $params['total_chunks'];

		$file_system = Filesystem::getInstance();

		// Create a temporary directory if not exists
		$temp_dir = trailingslashit( FileUtil::upload_tmp_dir() );
		if ( ! $file_system->exists( $temp_dir ) && ! $file_system->mkdir( $temp_dir, 0755 ) ) {
			return new WP_REST_Response(
				[ 'message' => esc_attr__( 'Failed to create temporary directory', 'advanced-fields-for-elementor-forms' ) ],
				400
			);
		}

		// Save the chunk
		$chunk_data = $file_system->get_contents( $files['file_chunk']['tmp_name'] );
		$temp_file_path = sprintf( '%s-%s.part%d', path_join( $temp_dir, $file_name ), $uniq_id, $chunk_index );

		if ( ! $file_system->put_contents( $temp_file_path, $chunk_data ) ) {
			return new WP_REST_Response(
				[ 'message' => esc_attr__( 'Failed to upload chunk!', 'advanced-fields-for-elementor-forms' ) ],
				400
			);
		}

		// Check if all chunks are uploaded
		if ( ($chunk_index + 1) === $total_chunks ) {
			// Merge chunks
			$temp_file = wp_tempnam( $file_name, $temp_dir );
			$output_file = fopen( $temp_file, 'wb' );
			for ( $i = 0; $i < $total_chunks; $i++ ) {
				$chunk_path = sprintf( '%s-%s.part%d', path_join( $temp_dir, $file_name ), $uniq_id, $i );
				$chunk_data = $file_system->get_contents( $chunk_path );
				fwrite( $output_file, $chunk_data );
				$file_system->delete( $chunk_path ); // Remove chunk after merging
				// make sure the temp file is deleted on shutdown
				register_shutdown_function(
				// Remove chunk after merging
					static fn() => $file_system->delete( $chunk_path )
				);
			}
			fclose( $output_file );
			// Remove temporary directory if empty
			// $file_system->rmdir( $temp_dir );

			$result = [
				'message'  => esc_attr__( 'File uploaded successfully', 'advanced-fields-for-elementor-forms' ),
				'tempName' => basename( $temp_file ),
				'name'     => $file_name,
			];

			$result['value'] = wp_json_encode(
				[
					'tempName' => $result['tempName'],
					'name'     => $result['name'],
				]
			);

			return rest_ensure_response( $result );
		}

		return rest_ensure_response(
			[
				'message' => esc_attr__(
					'Chunk uploaded successfully',
					'advanced-fields-for-elementor-forms'
				),
			]
		);
	}
}
