<?php
namespace ONLINE_ADAv4;

use iio\libmergepdf\Merger;
use ONLINE_ADAv4\WCAG_Scan;
use ONLINE_ADAv4\Helper;
use Symfony\Polyfill\Mbstring\Mbstring as PollyMb;

add_action("wp_ajax__oadaas__get_scan_details", __NAMESPACE__ . '\\get_scan_details');
function get_scan_details()
{
	Helper::verify_security($_GET);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$scan = get_active_scan();
	$details = [];
	$allPages = [];

	$details["include_query_strings"] = get_post_meta($scan->ID, "_oadaas_use_query_strings", true);
	$details["_oadaas_include_cbr"] = get_post_meta($scan->ID, "_oadaas_include_cbr", true);
	$domain = Plugin::$instance->info["home_url"];
	$details["scan_id"] = $scan->ID;
	$details["scan_step"] = get_post_meta($scan->ID, "_oadaas_scan-step", true);

	//Effectively starts the scan
	if (empty($details["scan_step"])) {
		$scan = new WCAG_Scan($scan->ID);
		$scan->process();
		$details["scan_step"] = $scan->current_step;
	}

	if ($details["scan_step"] == "ada-scan") {
		$details["sitemap"] = Helper::get_sitemap();
		$pages_scanned = get_post_meta($scan->ID, "_oadaas_pages_scanned", true);
		if (empty($pages_scanned)) {
			$pages_scanned = [];
		}

		if (!$details["include_query_strings"]) {
			unset($details["sitemap"]["query_links"]);
		}

		//Compare sitemap and pages scanned and return Sitemap - pages scanned
		foreach ($details["sitemap"] as $k => $v) {
			//$k == "non_query_links
			//$v = array of pages
			foreach ($v as $page) {
				if($k == "non_query_links"){
					$parsed_page = wp_parse_url($page)["path"];
				}
				if($k == "query_links"){
					 $parsed = wp_parse_url($page);
					 $parsed_page = $parsed["path"] . "?" . $parsed["query"];
				}
				
				if(empty($parsed_page)){
					$parsed_page = "/";
				}
				$allPages[] = $parsed_page;
			}
		}

		$details["pages_remaining"] = array_values(array_diff($allPages, $pages_scanned));
	}

	if ($details["scan_step"] == "color-blind-report") {
		$details["homepage"] = $domain;
		$details["filter_step"] = $scan->filter_step;
		$details["status"] = $scan->status;

		$cbr_complete = get_post_meta($scan->ID, "_oadaas_cbr_complete", true);

		if (empty($cbr_complete)) {
			$details["cbr_complete"] = false;
		}
		if ($cbr_complete) {
			$details["cbr_complete"] = true;
		}
	}

	if ($details["scan_step"] == "scan_finished") {
		$details["status"] = $scan->status;
	}

	echo wp_json_encode($details);
	exit;
}

add_action("wp_ajax__oadaas__dismiss_scan", __NAMESPACE__ . '\\dismiss_scan');
function dismiss_scan()
{
	Helper::verify_security($_GET);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$scan = get_active_scan();
	update_post_meta($scan->ID, '_oadaas_scan-dismissed', 1);
	wp_die();
}

/**
 * Displays the progress metabox contents when using ajax to refresh the view area.
 */
add_action("wp_ajax__oadaas__update_progress_metabox", __NAMESPACE__ . '\\progress_metabox');
function progress_metabox()
{
	Helper::verify_security($_POST);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$scan = new WCAG_Scan((int)$_POST['scan_id']);

	if (!$scan) return;

	// Make the active scan become the "queried" scan, which is what the metabox wants.
	global $post;
	$post = $scan->post;

	display_progress_metabox();
	exit;
}

function delete_chunks($scan_id)
{
	$chunks_total = get_post_meta($scan_id, "total_chunks", true);
	if (!empty($chunks_total)) {

		for ($i = 0; $i < $chunks_total; $i++) {
			delete_post_meta($scan_id, "chunk_" . $i);
		}
		delete_post_meta($scan_id, "total_chunks");
	}
}

add_action("wp_ajax__oadaas__save_chunks", __NAMESPACE__ . '\\save_chunks');
function save_chunks()
{
	Helper::verify_security($_POST);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$scan = get_active_scan();
	$last_chunk = $_POST["current_chunk"] == ((int)$_POST["chunks"] - 1);
	
	if (is_null($_POST["store"]) ||
		is_null($_POST["chunks"]) ||
		is_null($_POST["current_chunk"])) {
		wp_send_json_error(["msg" => "one of the necessary variables was empty."]);
	}

	//Only get here is there is more than 1 chunk
	if (!$last_chunk) {
		//Store each value as a separate post meta field.

		if ((int)$_POST["current_chunk"] === 0) {
			//Delete any results if they exist already
			delete_chunks($scan->ID);

			//This isn't the last chunk, so save the total chunks
			update_post_meta($scan->ID, "total_chunks", $_POST["chunks"]);
		}

		$result = update_post_meta($scan->ID, "chunk_" . $_POST["current_chunk"], $_POST["store"]);

		wp_send_json(["success" => true, "action" => $_POST["name"], "status" => $_POST["current_chunk"] + 1 . " of " . $_POST["chunks"]], 200);
	}

	//If 1 chunk or multiple chunks
	if ($last_chunk) {
		$result = "";
		switch($_POST["name"]){
			case "filter":
				$result = save_filter($scan);
				break;
			case "scan_results":
				if(is_null($_POST["page"])){
					wp_send_json(["msg" => "The page paramater was missing from the request"]);
				}
				
				$result = save_scan_results($scan->ID);
				break;
			case "snapshot":
				$result = save_snapshot($scan->ID);
				break;
		}

		delete_chunks($scan->ID);

		wp_send_json(["success" => true, "action" => $_POST["name"], "status" => $result], 200);
	}
}

add_action("wp_ajax__oadaas__empty_results", __NAMESPACE__ . '\\save_empty_page');
function save_empty_page()
{
	Helper::verify_security($_GET);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$scan = get_active_scan();
	$page = $_GET["page"];
	$pages_scanned = get_post_meta($scan->ID, "_oadaas_pages_scanned", true);

	if (empty($pages_scanned)) {
		$pages_scanned = [];
	}

	$pages_scanned[] = $page;

	update_post_meta($scan->ID, "_oadaas_pages_scanned", $pages_scanned);
	wp_send_json(["success" => true], 200);
}

add_action("wp_ajax__oadaas__mark_complete", __NAMESPACE__ . '\\mark_step_complete');
function mark_step_complete()
{
	Helper::verify_security($_POST);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$scan = get_active_scan();
	$result = $scan->step_complete();
	echo wp_kses($result,wp_kses_allowed_html());
	wp_die();
}

function save_filter($scan)
{
	$result_string = reassemble_chunks($scan->ID);
	$pdf_data = $result_string;
	$status = "success";
	$filename = sanitize_text_field($_POST["filter_name"]) . ".pdf";
	$dir_path = wp_upload_dir()["basedir"] . '/oadaas' . '/color-blind-report';

	if (!file_exists($dir_path)) {
        wp_mkdir_p($dir_path, 0777, true);
	}

	$file_path = $dir_path . "/" . $filename;
	$data = base64_decode($pdf_data);
	$result = file_put_contents($file_path, $data);  // phpcs:ignore

	if ($scan->filter_step == 9) {

		//Create PDF from all of the images and delete the images
		//Create pub path for the PDF and update post meta

		$dir_path = wp_upload_dir()["basedir"] . '/oadaas' . '/color-blind-report';
		$pub_path = wp_upload_dir()["baseurl"] . '/oadaas' . '/color-blind-report';
		$filters = format_filters($dir_path);

		$merger = new Merger;

		foreach ($filters as $filter) {
			$file_path = $dir_path . "/" . $filter;
			$merger->addFile($file_path);
		}

		$filename = "cbr" . ".pdf";
		$file_path = $dir_path . "/" . $filename;
		$new = $merger->merge();

		$file = fopen($file_path, "w");  // phpcs:ignore
		fwrite($file, $new);  // phpcs:ignore
		fclose($file);  // phpcs:ignore
		gc_collect_cycles();

		update_option("_oadaas_cbr_paths", ["abs_path" => $file_path, "pub_path" => $pub_path . "/" . $filename]);

		//Delete remnant files
		foreach ($filters as $filter) {
			$file_path = $dir_path . "/" . $filter;
			wp_delete_file($file_path);
		}

		$status = "finished";
	}

	return $status;
}

function save_snapshot($id)
{
	$result_string = reassemble_chunks($id);
	$image_b64 = base64_decode($result_string);
	$file = wp_upload_dir()["basedir"] . "/oadaas/snapshot.png";
	$result = file_put_contents($file, $image_b64);  // phpcs:ignore
	update_post_meta($id, "_oadaas_get_snapshot", 0);

	return wp_upload_dir()["baseurl"] . "/oadaas/snapshot.png";
}

function save_scan_results($id){
	$page = sanitize_text_field($_POST['page']);
	if ($page == " ") {
		$page = "Homepage";
	}

	$result_string = reassemble_chunks($id);
	$results_final = base64_decode($result_string);
	$results_final = rawurldecode($results_final); //<-- url encoding on front end now
	$utf8 = PollyMb::mb_convert_encoding($results_final, 'UTF-8', PollyMb::mb_detect_encoding($results_final, PollyMb::mb_detect_order(), true));

	if($utf8!==false){
		$results_final = $utf8;
	}
	$results_final = json_decode($results_final, true);
	
	if (!empty($results_final)) {
		try {

			$args = [
				"scanID" => $id,
				"page" => $page,
				"page_results" => $results_final
			];
			$result = Helper::save_scan_data($args);

			$pages_scanned = get_post_meta($id, "_oadaas_pages_scanned", true);

			if (empty($pages_scanned)) {
				$pages_scanned = [];
			}

			$pages_scanned[] = $page;

			update_post_meta($id, "_oadaas_pages_scanned", $pages_scanned);

			return "success";

		} catch (\Exception $e) {
			wp_send_json_error(["msg" => 'Caught exception: ', $e->getMessage(), "\n"]);
		}
	}
}

function format_filters($dir_path)
{
	$scanned_files = scandir($dir_path);
	$formatted = [];

	foreach ($scanned_files as $f) {
		switch ($f) {
			case "normal.pdf":
				$formatted[0] = $f;
				break;
			case "achromatomaly.pdf":
				$formatted[1] = $f;
				break;
			case "achromatopsia.pdf":
				$formatted[2] = $f;
				break;
			case "deuteranomaly.pdf":
				$formatted[3] = $f;
				break;
			case "deuteranopia.pdf":
				$formatted[4] = $f;
				break;
			case "protanomaly.pdf":
				$formatted[5] = $f;
				break;
			case "protanopia.pdf":
				$formatted[6] = $f;
				break;
			case "tritanomaly.pdf":
				$formatted[7] = $f;
				break;
			case "tritanopia.pdf":
				$formatted[8] = $f;
				break;
		}
	}

	ksort($formatted);

	return $formatted;
}

add_action("wp_ajax__oadaas__update_filter_step", __NAMESPACE__ . '\\update_filter_step');
function update_filter_step()
{
	Helper::verify_security($_POST);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$scan = get_active_scan();
	$step = get_post_meta($scan->ID, "_filter_step", true);
	$status = update_post_meta($scan->ID, "_filter_step", (int)$step + 1);
	echo wp_kses($status,wp_kses_allowed_html());
	wp_die();
}

add_action("wp_ajax__oadaas__dismiss_free_banner", __NAMESPACE__ . '\\dismiss_free_banner');
function dismiss_free_banner()
{
	Helper::verify_security($_POST);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	set_transient("_oadaas_upgrade_banner_dismissed", 1, 120 * DAY_IN_SECONDS);
	wp_send_json(["message" => "success"], 200);
}

function reassemble_chunks($id){
	$string = "";
	$chunks_total = "";

	if(isset($_POST["chunks"])){
		$chunks_total = $_POST["chunks"];
	}
	if(!isset($_POST["chunks"])){
		$chunks_total = get_post_meta($id, "total_chunks", true);
	}
	if(empty($chunks_total)){
		wp_send_json_error(["msg" => "Could not retrieve chunks from database"]);
	}

	if((int)$chunks_total > 1){
		for ($i = 0; $i < $chunks_total; $i++) {
			$string .= get_post_meta($id, "chunk_" . $i, true);
		}
	}

	$string .= $_POST["store"];
	return $string;
}

add_action("wp_ajax__oadaas__get_scan_results", __NAMESPACE__ . '\\get_scan_results');

function get_scan_results(){
	Helper::verify_security($_POST);

	// Add capability check to ensure user has proper permissions
	if (!current_user_can('manage_options')) {
		wp_send_json_error('Unauthorized access', 403);
		wp_die();
	}
	
	// Add referrer check to ensure request comes from your admin pages
	$referer = wp_get_referer();
	if (!$referer || strpos($referer, admin_url()) !== 0) {
		wp_send_json_error('Invalid request origin', 403);
		wp_die();
	}

	$results = Helper::get_scan_data($_POST["scan_id"], $_POST["offset"], $_POST["limit"]);
	$rows = Helper::get_row_count($_POST["scan_id"]);
	
	if($rows < 1){
		wp_send_json(["results" => "no results", "rows" => $rows]);
	}
	wp_send_json( 
		[
			"results"=> $results, 
			"rows" => $rows
		] , 200);
}