<?php

namespace ONLINE_ADAv4;

use ONLINE_ADAv4\Plugin;
use ONLINE_ADAv4\Menus;

add_action("admin_init", function(){
	
});

class Helper
{
	static function get_images_list(){
		$all = get_option("_oadaas_images_fix_list"); //Array of ids
		if(empty($all)){
			return false;
		}

		return $all;
	}

	static function media_extensions(){
		return ["jpg", "jpeg", "png", "gif", "ico", "pdf", "doc", "docx", "ppt", "pptx", "pps", "ppsx", "odt", "xls", "xlsx", "psd", "mp3", "m4a", "ogg", "wav", "mp4", "m4v", "mov", "wmv", "avi", "mpg", "ogv", "3gp", "3g2", "svg"];
	}

	static function is_pro(){
		return filter_var(get_option("accessibility-suite-pro-license-status"), FILTER_VALIDATE_INT) === 1;
	}

	static function get_env_vars()
	{
		return [
			"post_max_size" => ini_get("post_max_size"),
			"upload_max_filesize" => ini_get("upload_max_filesize"),
			"max_input_time" => ini_get("max_input_time"),
			"max_input_nesting_level" => ini_get("max_input_nesting_level"),
			"max_execution_time" => ini_get("max_execution_time"),
			"memory_limit" => ini_get("memory_limit"),
			"max_input_vars" => ini_get("max_input_vars")
		];
	}

	static function get_sitemap(){
		if(Helper::is_pro()){
			return get_option("_oadaas_sitemap");
		}

		return ["non_query_links" => [sanitize_text_field(untrailingslashit(home_url()))]];
	}

	static function create_table()
	{
		global $wpdb;
        $table_name = $wpdb->prefix.'oada_scans';

		if(!$wpdb->query($wpdb->prepare("SELECT * FROM information_schema.tables WHERE table_name = $table_name LIMIT 1;"))){ // phpcs:ignore
			$charset_collate = $wpdb->get_charset_collate();

			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
			dbDelta($wpdb->prepare("CREATE TABLE $table_name (
				ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
				scanID bigint(20) unsigned NOT NULL,
				page text NOT NULL,
				page_results mediumtext NOT NULL,
				PRIMARY KEY  (ID)
			) $charset_collate;")); // phpcs:ignore
		}
	}

	static function create_false_positives_table(){
		global $wpdb;

		$table_name = $wpdb->prefix . "oada_false_positives";

		//Table does not exist already
		if(!$wpdb->query($wpdb->prepare("SELECT * FROM information_schema.tables WHERE table_name = $table_name LIMIT 1"))){ // phpcs:ignore
			$charset_collate = $wpdb->get_charset_collate();

			require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
			dbDelta($wpdb->prepare("CREATE TABLE $table_name (
				ID bigint(20) unsigned NOT NULL AUTO_INCREMENT,
				scan_id bigint(20) unsigned NOT NULL,
				list longtext NOT NULL,
				PRIMARY KEY  (ID)
			) $charset_collate;"));

			$scans = $wpdb->get_results("SELECT DISTINCT scanID FROM {$wpdb->prefix}oada_scans"); // phpcs:ignore
				
			foreach($scans AS $scan){
				$arr = $wpdb->_real_escape(json_encode([]));
				$wpdb->query($wpdb->prepare("INSERT INTO $table_name (scan_id, list) VALUES ($scan->scanID, '$arr')"));// phpcs:ignore
			}
		}
	}

	static function save_false_positive($scan_id, $issue_id){
		global $wpdb;
		$table_name = $wpdb->prefix.'oada_false_positives';
	
		if(! is_admin()) {
			return '';
		}
	
		// Validate inputs
		$scan_id = absint($scan_id); // Ensure scan_id is a positive integer
		
		if (!$scan_id) {
			return ["status" => "failed", "msg" => "Invalid scan ID"];
		}
		
		try{
			// Get list using properly prepared query
			$query = $wpdb->prepare(
				"SELECT list FROM %i WHERE scan_id = %d",
				$table_name,
				$scan_id
			);
			
			$result = $wpdb->get_results($query);
			
			if (empty($result)) {
				return ["status" => "failed", "msg" => "Scan not found"];
			}
			
			$list = json_decode($result[0]->list);
			
			// Validate list is an array
			if (!is_array($list)) {
				$list = [];
			}
			
			// Add to list
			$list[] = $issue_id;
			
			// Prepare the JSON string properly
			$json_list = wp_json_encode($list);
			
			// Update with properly prepared query
			$updated = $wpdb->update(
				$table_name,
				['list' => $json_list],
				['scan_id' => $scan_id],
				['%s'],
				['%d']
			);
			
			if ($updated === false) {
				return ["status" => "failed", "msg" => "Database update failed"];
			}
			
			return ["status" => "success"];
		} catch(\Exception $e){
			return ["status" => "failed", "msg" => $e->getMessage()];
		}
	}
	

	static function delete_false_positive($scan_id, $issue_id){
		global $wpdb;
        $table_name = $wpdb->prefix.'oada_false_positives';

		try{
			//Get list
			$list = json_decode(
				$wpdb->get_results($wpdb->prepare("SELECT list FROM $table_name WHERE scan_id = $scan_id"))[0]->list // phpcs:ignore
			);

			//remove from list
			$key = array_search($issue_id, $list);
			unset($list[$key]);
			$list = $wpdb->_real_escape(json_encode($list));

			//Save new list
			$wpdb->query($wpdb->prepare("UPDATE $table_name SET list = '$list' WHERE scan_id = $scan_id")); // phpcs:ignore
			return ["status" => "success"];
		}catch(\Exception $e){
			return ["status" => "failed", "msg" => $e];
		}
	}

	static function get_false_positives($scan_id){
		global $wpdb;
        $table_name = $wpdb->prefix .'oada_false_positives';
        $result = $wpdb->get_results($wpdb->prepare("SELECT list FROM $table_name WHERE scan_id = $scan_id"));  // phpcs:ignore
        if($result) {

            return json_decode($result[0]->list);
        }
        return null;
	}
	
	static function get_row_count($scan_id){
		if (empty($scan_id)) {
			return false;
		}

		global $wpdb;
		$table_name = $wpdb->prefix . "oada_scans";

		$rows = (array)$wpdb->get_results($wpdb->prepare("SELECT COUNT(*) as 'rows' FROM $table_name WHERE scanID = $scan_id")); // phpcs:ignore
		$rows = (array)$rows[0];
		
		return (int)$rows["rows"];
	}
	
	static function get_scan_data_automatic($scan_id, $limit){
		if (empty($scan_id)) {
			return false;
		}

		global $wpdb;
		$results = [];
		$offset = 0;
		$table_name = $wpdb->prefix . "oada_scans";
		$total_rows = self::get_row_count($scan_id);

		while($offset <= $total_rows){
			$query_results = (array)$wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE scanID = $scan_id LIMIT $offset, $limit")); // phpcs:ignore
			$results = array_merge($results, $query_results);

			$offset += $limit;
		}

		$sendBack = [
			"errors" => [],
			"alerts" => [],
			"contrast" => [],
			"issues" => []
		];

		foreach ($results as $row) {
			$row = (array)$row;
			$row['page_results'] = json_decode($row['page_results']);
			
			$sendBack["errors"] = array_merge($sendBack["errors"], (array)$row['page_results']["errors"]);
			$sendBack["contrast"] = array_merge($sendBack["contrast"], (array)$row['page_results']["contrast"]);
			$sendBack["alerts"] = array_merge($sendBack["alerts"], (array)$row['page_results']["alerts"]);
			$sendBack["issues"] = array_merge($sendBack["issues"], (array)$row['page_results']["issues"]);
		}

		return $sendBack;
	}

	static function get_scan_data($scan_id, $offset = 0, $limit = 0)
	{
		if (empty($scan_id)) {
			return false;
		}

		global $wpdb;
		$table_name = $wpdb->prefix . "oada_scans";

		if($limit === 0){
            $results = (array)$wpdb->get_results($wpdb->prepare( "SELECT * FROM $table_name WHERE scanID = $scan_id")); // phpcs:ignore
		} else {
            $results = (array)$wpdb->get_results($wpdb->prepare( "SELECT * FROM $table_name WHERE scanID = $scan_id LIMIT $offset, $limit")); // phpcs:ignore
        }
		
		$sendBack = [
			"errors" => [],
			"alerts" => [],
			"contrast" => [],
			"issues" => []
		];

		foreach ($results as $row) {
			$row = (array)$row;
			$row['page_results'] = json_decode(wp_json_encode(json_decode($row['page_results'])), true);
			
			if( isset($row['page_results']["errors"])){
				if(!empty($row['page_results']["errors"])){
					$sendBack["errors"] = array_merge($sendBack["errors"], $row['page_results']["errors"]);
				}
			}
			if( isset($row['page_results']["contrast"]) ){
				if(!empty($row['page_results']["contrast"])){
					$sendBack["contrast"] = array_merge($sendBack["contrast"], $row['page_results']["contrast"]);
				}
			}
			if( isset($row['page_results']["alerts"]) ){
				if(!empty($row['page_results']["alerts"])){
					$sendBack["alerts"] = array_merge($sendBack["alerts"], $row['page_results']["alerts"]);
				}
			}
			if( isset($row['page_results']["issues"]) ){
				if(!empty($row['page_results']["issues"])){
					$sendBack["issues"] = array_merge($sendBack["issues"], $row['page_results']["issues"]);
				}
			}
			
		}

		return $sendBack;
	}
	static function save_scan_data($args)
	{
		if (gettype($args) == "array") {
			$args = (object)$args;
		}
		if (gettype($args) !== "object") {
			return false;
		}

		global $wpdb;

		$table_name = $wpdb->prefix . "oada_scans";

		$success = $wpdb->insert($table_name, array( // phpcs:ignore
			"scanID" => $args->scanID,
			"page" => $args->page,
			"page_results" => json_encode($args->page_results)
		));

		return $success;
	}
	static function delete_scan_data($scan_id)
	{
		if (empty($scan_id)) {
			return false;
		}

		global $wpdb;
		$table_name = $wpdb->prefix . "oada_scans";

		$success = $wpdb->delete($table_name, ['scanID' => $scan_id]); // phpcs:ignore
		return $success;
	}
	
	static function getSection508ArticlesModel()
	{
		$s508 = [
			"guideline" => "1194.22",
			"a" => [
				'title' => 'A text equivalent for every non-text element shall be provided (e.g., via "alt", "longdesc", or in element content).',
				'description' => '',
			],
			"b" => [
				'title' => 'Equivalent alternatives for any multimedia presentation shall be synchronized with the presentation.',
				'description' => '',
			],
			"c" => [
				'title' => 'Web pages shall be designed so that all information conveyed with color is also available without color, for example from context or markup.',
				'description' => '',
			],
			"d" => [
				'title' => 'Documents shall be organized so they are readable without requiring an associated style sheet.',
				'description' => '',
			],
			"e" => [
				'title' => 'Redundant text links shall be provided for each active region of a server-side image map.',
				'description' => '',
			],
			"f" => [
				'title' => 'Client-side image maps shall be provided instead of server-side image maps except where the regions cannot be defined with an available geometric shape.',
				'description' => '',
			],
			"g" => [
				'title' => 'Row and column headers shall be identified for data tables.',
				'description' => '',
			],
			"h" => [
				'title' => 'Markup shall be used to associate data cells and header cells for data tables that have two or more logical levels of row or column headers.',
				'description' => '',
			],
			"i" => [
				'title' => 'Frames shall be titled with text that facilitates frame identification and navigation.',
				'description' => '',
			],
			"j" => [
				'title' => 'Pages shall be designed to avoid causing the screen to flicker with a frequency greater than 2 Hz and lower than 55 Hz.',
				'description' => '',
			],
			"k" => [
				'title' => 'A text-only page, with equivalent information or functionality, shall be provided to make a web site comply with the provisions of this part, when compliance cannot be accomplished in any other way. The content of the text-only page shall be updated whenever the primary page changes.',
				'description' => '',
			],
			"l" => [
				'title' => 'When pages utilize scripting languages to display content, or to create interface elements, the information provided by the script shall be identified with functional text that can be read by assistive technology.',
				'description' => '',
			],
			"m" => [
				'title' => 'When a web page requires that an applet, plug-in or other application be present on the client system to interpret page content, the page must provide a link to a plug-in or applet that complies with 1194.21(a) through (l).',
				'description' => '',
			],
			"n" => [
				'title' => 'When electronic forms are designed to be completed on-line, the form shall allow people using assistive technology to access the information, field elements, and functionality required for completion and submission of the form, including all directions and cues.',
				'description' => '',
			],
			"o" => [
				'title' => 'A method shall be provided that permits users to skip repetitive navigation links.',
				'description' => '',
			],
			"p" => [
				'title' => 'When a timed response is required, the user shall be alerted and given sufficient time to indicate more time is required.',
				'description' => '',
			],
		];

		return $s508;
	}
	static function getWcagArticlesModel($level = 0, $guidelinesOnly = false)
	{
		$level = (int)$level;
		if (!is_int($level)) {
			return "Level param must be of type integer";
		}
		$wcag = array(
			array(
				"principle_heading" => "<a href='" . Plugin::$instance->info["ext-quickref"] . '#principle1' . "' target='_blank' title='Principle 1' rel='external'>Principle 1 - Perceivable</a>",
				"principle_sub_heading" => "Information and user interface components must be presentable to users in ways they can perceive.",
				"principle_guidelines" => [
					"1.1" => [
						"heading" => "Guideline 1.1 – Text Alternatives",
						"subheading" => "Provide text alternatives for any non-text content so that it can be changed into other forms people need, such as large print, braille, speech, symbols or simpler language.",
						"level" => [
							"A" => [
								'1.1.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#non-text-content',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.1.1',
									'title' => "Non-text Content",
									"message" => 'All non-text content that is presented to the user has a text alternative that serves the equivalent purpose.',
									'tip' => 'Non-text files such as images or PDFs need to have plain-english alt text descriptions that describe the contents of the image.',
								],
							],
							"AA" => []
						]
					],
					"1.2" => [
						"heading" => "Guideline 1.2 – Time-based Media",
						"subheading" => "Provide alternatives for time-based media.",
						"level" => [
							"A" => [
								'1.2.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#audio-only-and-video-only-prerecorded',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.2.1',
									'title' => "Audio-only and Video-only (Prerecorded)",
									"message" => 'For prerecorded audio-only and prerecorded video-only media, the following are true, except when the audio or video is a media alternative for text and is clearly labeled as such:
										<div class="bullet"><span>Prerecorded Audio-only:</span> An alternative for time-based media is provided that presents equivalent information for prerecorded audio-only content.</div>
										<div class="bullet"><span>Prerecorded Video-only:</span> Either an alternative for time-based media or an audio track is provided that presents equivalent information for prerecorded video-only content</div>',
									'tip' => 'If video or audio is presented on your site, you need to present a text alternative, such as a transcript.',
								],
								'1.2.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#captions-prerecorded',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.2.2',
									'title' => "Captions (Prerecorded)",
									"message" => 'Captions are provided for all prerecorded audio content in synchronized media, except when the media is a media alternative for text and is clearly labeled as such.',
									'tip' => 'Synchronized media, such as a video with audio (YouTube video is a good example) needs captions displayed as part of the media file.',
								],
								'1.2.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#audio-description-or-media-alternative-prerecorded',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.2.3',
									'title' => "Audio Description or Media Alternative (Prerecorded)",
									"message" => 'An alternative for time-based media or audio description of the prerecorded video content is provided for synchronized media, except when the media is a media alternative for text and is clearly labeled as such.',
									'tip' => 'Synchronized media, such as a video with audio (YouTube video is a good example) needs captions displayed as part of the media file.',
								],

							],
							"AA" => [
								'1.2.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#captions-live',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.2.4',
									'title' => "Captions are provided for all live audio content in synchronized media.",
									"message" => 'An alternative for time-based media or audio description of the prerecorded video content is provided for synchronized media, except when the media is a media alternative for text and is clearly labeled as such.',
									'tip' => 'If you’re displaying live video or audio, you need captions enabled (likely, this will be something to confirm through your 3rd-party media provider, such as LiveStream or your Webinar software)',
								],
								'1.2.5' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#audio-description-prerecorded',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.2.5',
									'title' => "Audio Description (Prerecorded)",
									"message" => 'Audio description is provided for all prerecorded video content in synchronized media.',
									'tip' => '',
								],
							]
						]
					],
					"1.3" => [
						"heading" => "Guideline 1.3 – Adaptable",
						"subheading" => "Create content that can be presented in different ways (for example simpler layout) without losing information or structure.",
						"level" => [
							"A" => [
								'1.3.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#info-and-relationships',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.3.1',
									'title' => "Info and Relationships",
									"message" => 'Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text.',
									'tip' => '',
								],
								'1.3.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#meaningful-sequence',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.3.2',
									'title' => "Meaningful Sequence",
									"message" => 'When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined.',
									'tip' => 'You’ll need proper use of heading tags (H1, H2, etc…) and a text description or alternative to direct people to the order that content should be consumed.',
								],
								'1.3.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#sensory-characteristics',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.3.3',
									'title' => "Sensory Characteristics",
									"message" => 'Instructions provided for understanding and operating content do not rely solely on sensory characteristics of components such as shape, size, visual location, orientation, or sound.',
									'tip' => 'You can’t have an instruction on the website that refers to a sensory characteristic as the only way to identify something. For example, the text “Click on the round button to submit your application” wouldn’t be compliant, because the instruction refers only to a sensory characteristic, in this case a ‘round’ button, which would be indistinguishable to a blind person.',
								],
							],
							"AA" => [
								'1.3.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#orientation',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.3.4',
									'title' => "Orientation",
									"message" => 'Content does not restrict its view and operation to a single display orientation, such as portrait or landscape, unless a specific display orientation is essential.',
									'tip' => '',
								],
								'1.3.5' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#identify-input-purpose',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.3.5',
									'title' => "Identify Input Purpose",
									"message" => 'The purpose of each input field collecting information about the user can be programmatically determined when:
										<div class="bullet">The input field serves a purpose identified in the Input Purposes for User Interface Components section; and</div>
										<div class="bullet">The content is implemented using technologies with support for identifying the expected meaning for form input data.</div>',
									'tip' => 'Check the purpose of the input against the list <a href="https://www.w3.org/TR/WCAG21/#input-purposes">here</a> and if the purpose for the input is on the list, then make sure the input has the attribute "autocomplete" with the corresponding value from the list, i.e. autocomplete="email".',
								],
							]
						]
					],
					"1.4" => [
						"heading" => "Guideline 1.4 – Distinguishable",
						"subheading" => "Make it easier for users to see and hear content including separating foreground from background.",
						"level" => [
							"A" => [
								'1.4.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#use-of-color',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.1',
									'title' => "Use of Color",
									"message" => 'Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.',
									'tip' => 'A reference to color can’t be the only way to distinguish something. For example, the text “Click on the green button to submit your application” wouldn’t be compliant, because the instruction refers only to the color green, which would be indistinguishable to a blind person.',
								],
								'1.4.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#audio-control',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.2',
									'title' => "Audio Control",
									"message" => 'If any audio on a Web page plays automatically for more than 3 seconds, either a mechanism is available to pause or stop the audio, or a mechanism is available to control audio volume independently from the overall system volume level.',
									'tip' => 'As a general best practice outside of accessibility compliance, you shouldn’t have any audio auto-playing. It’s a conversion killer. But if you do, you need a mechanism to be able to pause or stop the audio, and it needs to be navigable via keyboard.',
								],

							],
							"AA" => [
								'1.4.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#contrast-minimum',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.3',
									'title' => "Contrast (Minimum)",
									"message" => 'The visual presentation of text and images of text has a contrast ratio of at least 4.5:1, except for the following:
										<div class="bullet"><span>Large Text:</span> Large-scale text and images of large-scale text have a contrast ratio of at least 3:1.</div>
										<div class="bullet"><span>Incidental:</span> Text or images of text that are part of an inactive user interface component, that are pure decoration, that are not visible to anyone, or that are part of a picture that contains significant other visual content, have no contrast requirement.</div>
										<div class="bullet"><span>Logotypes:</span> Text that is part of a logo or brand name has no minimum contrast requirement.</div>',
									'tip' => 'As a general best practice outside of accessibility compliance, you shouldn’t have any audio auto-playing. It’s a conversion killer. But if you do, you need a mechanism to be able to pause or stop the audio, and it needs to be navigable via keyboard.',
								],
								'1.4.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#resize-text',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.4',
									'title' => "Resize text",
									"message" => 'Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality.',
									'tip' => 'We interpret that you’ll meet accessibility compliance as long as your screen can be zoomed in up to 200% by using your keyboard (on PCs, it’s CTRL and +) without losing site function.',
								],
								'1.4.5' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#images-of-text',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.5',
									'title' => "Images of Text",
									"message" => "If the technologies being used can achieve the visual presentation, text is used to convey information rather than images of text except for the following:
										<div class='bullet'><span>Customizable:</span> The image of text can be visually customized to the user's requirements.</div>
										<div class='bullet'><span>Essential:</span> A particular presentation of text is essential to the information being conveyed.</div>",
									'tip' => 'Don’t bake text into an image file, because blind people can’t read text that’s saved as part of an image file. Logos are exempt from this, but your logo image file should have clear alt text that describes any text that is part of the logo.',
								],
								'1.4.10' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#reflow',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.10',
									'title' => "Reflow",
									"message" => "Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions for:
										<div class='bullet'><span>User Interface Components:</span> Visual information required to identify user interface components and states, except for inactive components or where the appearance of the component is determined by the user agent and not modified by the author;</div>
										<div class='bullet'><span>Graphical Objects:</span> Parts of graphics required to understand the content, except when a particular presentation of graphics is essential to the information being conveyed.",
									'tip' => '',
								],
								'1.4.11' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#non-text-contrast',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.11',
									'title' => "Non-text Contrast",
									"message" => "The visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s):
										<div class='bullet'>Vertical scrolling content at a width equivalent to 320 CSS pixels;</div>
										<div class='bullet'>Horizontal scrolling content at a height equivalent to 256 CSS pixels;</div>
									<div>Except for parts of the content which require two-dimensional layout for usage or meaning.</div>",
									'tip' => '',
								],
								'1.4.12' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#text-spacing',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.12',
									'title' => "Text Spacing",
									"message" => "In content implemented using markup languages that support the following text style properties, no loss of content or functionality occurs by setting all of the following and by changing no other style property:
										<div class='bullet'>Line height (line spacing) to at least 1.5 times the font size;</div>
										<div class='bullet'>Spacing following paragraphs to at least 2 times the font size;</div>
										<div class='bullet'>Letter spacing (tracking) to at least 0.12 times the font size;</div>
										<div class='bullet'>Word spacing to at least 0.16 times the font size.</div>
									<div>Exception: Human languages and scripts that do not make use of one or more of these text style properties in written text can conform using only the properties that exist for that combination of language and script.</div>",
									'tip' => '',
								],
								'1.4.13' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#content-on-hover-or-focus',
									'url' => Plugin::$instance->info["int-quickref"] . '#1.4.13',
									'title' => "Content on Hover or Focus",
									"message" => "Where receiving and then removing pointer hover or keyboard focus triggers additional content to become visible and then hidden, the following are true:
										<div class='bullet'><span>Dismissible:</span> A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus, unless the additional content communicates an input error or does not obscure or replace other content;</div>
										<div class='bullet'><span>Hoverable:</span> If pointer hover can trigger the additional content, then the pointer can be moved over the additional content without the additional content disappearing;</div>
										<div class='bullet'><span>Persistent:</span> The additional content remains visible until the hover or focus trigger is removed, the user dismisses it, or its information is no longer valid.</div>
									<div>Exception: The visual presentation of the additional content is controlled by the user agent and is not modified by the author.</div>",
									'tip' => '',
								],
							]
						]
					],
				]
			),
			array(
				"principle_heading" => "<a href='" . Plugin::$instance->info["ext-quickref"] . '#principle2' . "' target='_blank' title='Principle 2'>Principle 2 - Operable</a>",
				"principle_sub_heading" => "User interface components and navigation must be operable.",
				"principle_guidelines" => [
					"2.1" => [
						"heading" => "Guideline 2.1 – Keyboard Accessible",
						"subheading" => "Provide text alternatives for any non-text content so that it can be changed into other forms people need, such as large print, braille, speech, symbols or simpler language.",
						"level" => [
							"A" => [
								'2.1.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#keyboard',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.1.1',
									'title' => "Keyboard",
									"message" => "All functionality of the content is operable through a keyboard interface without requiring specific timings for individual keystrokes, except where the underlying function requires input that depends on the path of the user's movement and not just the endpoints.",
									'tip' => 'Your site needs to be navigable and functional by keyboard alone, meaning the user needs to be able to “tab” through all size pages, menus, buttons and forms, etc… And clicking “enter” submits anything that requires submission.',
								],
								'2.1.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#no-keyboard-trap',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.1.2',
									'title' => "No Keyboard Trap",
									"message" => "If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface, and, if it requires more than unmodified arrow or tab keys or other standard exit methods, the user is advised of the method for moving focus away.",
									'tip' => '',
								],
								'2.1.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#character-key-shortcuts',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.1.4',
									'title' => "Character Key Shortcuts",
									"message" => "If a keyboard shortcut is implemented in content using only letter (including upper- and lower-case letters), punctuation, number, or symbol characters, then at least one of the following is true:
										<div class='bullet'><span>Turn off:</span> A mechanism is available to turn the shortcut off;</div>,
										<div class='bullet'><span>Remap:</span> A mechanism is available to remap the shortcut to include one or more non-printable keyboard keys (e.g., Ctrl, Alt);</div>
										<div class='bullet'><span>Active only on focus:</span> The keyboard shortcut for a user interface component is only active when that component has focus.</div>",
									'tip' => '',
								],
							],
							"AA" => []
						]
					],
					"2.2" => [
						"heading" => "Guideline 2.2 – Enough Time",
						"subheading" => "Provide users enough time to read and use content.",
						"level" => [
							"A" => [
								'2.2.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#timing-adjustable',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.2.1',
									'title' => "Timing Adjustable",
									"message" => "For each time limit that is set by the content, at least one of the following is true:
										<div class='bullet'><span>Turn off:</span> The user is allowed to turn off the time limit before encountering it, or</div>
										<div class='bullet'><span>Adjust:</span> The user is allowed to adjust the time limit before encountering it over a wide range that is at least ten times the length of the default setting, or</div>
										<div class='bullet'><span>Extend:</span> The user is warned before time expires and given at least 20 seconds to extend the time limit with a simple action (for example, 'press the space bar'), and the user is allowed to extend the time limit at least ten times, or</div>
										<div class='bullet'><span>Real-time Exception:</span> The time limit is a required part of a real-time event (for example, an auction), and no alternative to the time limit is possible, or</div>
										<div class='bullet'><span>Essential Exception:</span> The time limit is essential and extending it would invalidate the activity, or</div>
										<div class='bullet'><span>20 Hour Exception:</span> The time limit is longer than 20 hours.</div>",
									'tip' => '',
								],
								'2.2.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#pause-stop-hide',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.2.2',
									'title' => "Pause, Stop, Hide",
									"message" => "For moving, blinking, scrolling, or auto-updating information, all of the following are true:
										<div class='bullet'><span>Moving, blinking, scrolling:</span> For any moving, blinking or scrolling information that (1) starts automatically, (2) lasts more than five seconds, and (3) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it unless the movement, blinking, or scrolling is part of an activity where it is essential, and</div>
										<div class='bullet'><span>Auto-updating:</span> For any auto-updating information that (1) starts automatically and (2) is presented in parallel with other content, there is a mechanism for the user to pause, stop, or hide it or to control the frequency of the update unless the auto-updating is part of an activity where it is essential.</div>",
									'tip' => '',
								],
							],
							"AA" => []
						]
					],
					"2.3" => [
						"heading" => "Guideline 2.3 – Seizures",
						"subheading" => "Do not design content in a way that is known to cause seizures.",
						"level" => [
							"A" => [
								'2.3.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#three-flashes-or-below-threshold',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.3.1',
									'title' => "Three Flashes or Below Threshold",
									"message" => "Web pages do not contain anything that flashes more than three times in any one second period, or the flash is below the general flash and red flash thresholds.",
									'tip' => '',
								],
							],
							"AA" => []
						]
					],
					"2.4" => [
						"heading" => "Guideline 2.4 – Navigable",
						"subheading" => "Provide ways to help users navigate, find content, and determine where they are.",
						"level" => [
							"A" => [
								'2.4.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#bypass-blocks',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.4.1',
									'title' => "Bypass Blocks",
									"message" => "A mechanism is available to bypass blocks of content that are repeated on multiple Web pages.",
									'tip' => 'Example: An online newspaper’s homepage might have a main story, 15 other stories, and 10 advertisements, which might total dozens of links and buttons, which would otherwise take a screen reader or keyboard a very long time to “tab” through and audibly read. You’ll need a link at the top of the page that says “jump to main story”, thus saving a blind person a lot of wasted time.',
								],
								'2.4.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#page-titled',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.4.2',
									'title' => "Page Titled",
									"message" => "Web pages have titles that describe topic or purpose.",
									'tip' => '',
								],
								'2.4.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#focus-order',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.4.3',
									'title' => "Focus Order",
									"message" => "If a Web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability.",
									'tip' => 'The order in which someone navigates from action/link to action/link needs to be in a logical order. In other words, “tabbing” through a webpage can’t result in nonsensical jumping around. Things must be in logical order.',
								],
								'2.4.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#link-purpose-in-context',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.4.4',
									'title' => "Link Purpose (In Context)",
									"message" => "The purpose of each link can be determined from the link text alone or from the link text together with its programmatically determined link context, except where the purpose of the link would be ambiguous to users in general.",
									'tip' => 'A link shouldn’t just say “click here”, or “link”. The text of the link should be descriptive to the contents of the link. Example: “There was much bloodshed during the Medieval period of history”, and “Medieval Period” is the link.',
								],
							],
							"AA" => [
								'2.4.5' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#multiple-ways',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.4.5',
									'title' => "Multiple Ways",
									"message" => "More than one way is available to locate a Web page within a set of Web pages except where the Web Page is the result of, or a step in, a process.",
									'tip' => 'You need to have more than one way to access a webpage. For example, the website’s main navigation menu represents one way to access a page. A second way to access a page would be having inter-linking between pages, or a secondary menu (like a sidebar menu, for example).',
								],
								'2.4.6' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#headings-and-labels',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.4.6',
									'title' => "Headings and Labels",
									"message" => "Headings and labels describe topic or purpose.",
									'tip' => 'This task permeates much of the site. Pages need to have proper headings to identify site content, and in the right order (H2 tags shouldn’t be in front of H1 tags, etc…). Also, embedded tables, objects, iFrames, YouTube videos, etc… all need to have proper headings. Assume that these heading tags won’t be provided by the embed code. You’ll need add them manually via HTML manipulation.',
								],
								'2.4.7' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#focus-visible',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.4.7',
									'title' => "Focus Visible",
									"message" => "Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible.",
									'tip' => 'As someone “tabs” through the website, there needs to be a visible cue as to where the cursor is at, and it needs to meet the 4.5:1 color contrast ratio. An example would be underlining words/links, or illuminating buttons.',
								],
							]
						]
					],
					"2.5" => [
						"heading" => "Guideline 2.5 – Input Modalities",
						"subheading" => "Make it easier for users to operate functionality through various inputs beyond keyboard.",
						"level" => [
							"A" => [
								'2.5.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#pointer-gestures',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.5.1',
									'title' => "Pointer Gestures",
									"message" => "All functionality that uses multipoint or path-based gestures for operation can be operated with a single pointer without a path-based gesture, unless a multipoint or path-based gesture is essential.",
									'tip' => '',
								],
								'2.5.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#pointer-cancellation',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.5.2',
									'title' => "Pointer Cancellation",
									"message" => "For functionality that can be operated using a single pointer, at least one of the following is true:
										<div class='bullet'><span>No Down-Event:</span> The down-event of the pointer is not used to execute any part of the function;</div>
										<div class='bullet'><span>Abort or Undo:</span> Completion of the function is on the up-event, and a mechanism is available to abort the function before completion or to undo the function after completion;</div>
										<div class='bullet'><span>Up Reversal:</span> The up-event reverses any outcome of the preceding down-event;</div>
										<div class='bullet'><span>Essential:</span> Completing the function on the down-event is essential.</div>",
									'tip' => '',
								],
								'2.5.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#label-in-name',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.5.3',
									'title' => "Label in Name",
									"message" => "For user interface components with labels that include text or images of text, the name contains the text that is presented visually.",
									'tip' => '',
								],
								'2.5.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#motion-actuation',
									'url' => Plugin::$instance->info["int-quickref"] . '#2.5.4',
									'title' => "Motion Actuation",
									"message" => "Functionality that can be operated by device motion or user motion can also be operated by user interface components and responding to the motion can be disabled to prevent accidental actuation, except when:
										<div class='bullet'><span>Supported Interface:</span> The motion is used to operate functionality through an accessibility supported interface;</div>
										<div class='bullet'><span>Essential:</span> The motion is essential for the function and doing so would invalidate the activity.</div>",
									'tip' => '',
								],
							],
						],
					]
				]
			),
			array(
				"principle_heading" => "<a href='" . Plugin::$instance->info["ext-quickref"] . '#principle3' . "' target='_blank' title='Principle 3'>Principle 3 - Understandable</a>",
				"principle_sub_heading" => "Information and the operation of user interface must be understandable.",
				"principle_guidelines" => [
					"3.1" => [
						"heading" => "Guideline 3.1 – Readable",
						"subheading" => "Make text content readable and understandable.",
						"level" => [
							"A" => [
								'3.1.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#language-of-page',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.1.1',
									'title' => "Language of Page",
									"message" => "The default human language of each Web page can be programmatically determined.",
									'tip' => 'A lang attribute on the HTML element needs to be present.',
								],
							],
							"AA" => [
								'3.1.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#language-of-parts',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.1.2',
									'title' => "Language of Parts",
									"message" => "The human language of each passage or phrase in the content can be programmatically determined except for proper names, technical terms, words of indeterminate language, and words or phrases that have become part of the vernacular of the immediately surrounding text.",
									'tip' => '',
								],
							]
						]
					],
					"3.2" => [
						"heading" => "Guideline 3.2 – Predictable",
						"subheading" => "Make Web pages appear and operate in predictable ways.",
						"level" => [
							"A" => [
								'3.2.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#on-focus',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.2.1',
									'title' => "On Focus",
									"message" => "When any component receives focus, it does not initiate a change of context.",
									'tip' => '',
								],
								'3.2.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#on-input',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.2.2',
									'title' => "On Input",
									"message" => "Changing the setting of any user interface component does not automatically cause a change of context unless the user has been advised of the behavior before using the component.",
									'tip' => '',
								],
							],
							"AA" => [
								'3.2.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#consistent-navigation',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.2.3',
									'title' => "Consistent Navigation",
									"message" => "Navigational mechanisms that are repeated on multiple Web pages within a set of Web pages occur in the same relative order each time they are repeated, unless a change is initiated by the user.",
									'tip' => '',
								],
								'3.2.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#consistent-identification',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.2.4',
									'title' => "Consistent Identification",
									"message" => "Components that have the same functionality within a set of Web pages are identified consistently.",
									'tip' => '',
								],
							]
						]
					],
					"3.3" => [
						"heading" => "Guideline 3.3 – Input Assistance",
						"subheading" => "Help users avoid and correct mistakes.",
						"level" => [
							"A" => [
								'3.3.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#error-identification',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.3.1',
									'title' => "Error Identification",
									"message" => "If an input error is automatically detected, the item that is in error is identified and the error is described to the user in text.",
									'tip' => 'This is common in forms. If someone enters incorrect data or skips a required field, a plain-text message or alert appears, letting the user know what to fix.',
								],
								'3.3.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#labels-or-instructions',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.3.2',
									'title' => "Labels or Instructions",
									"message" => "Labels or instructions are provided when content requires user input.",
									'tip' => 'Form fields need titles that describe what’s required of them.',
								],
							],
							"AA" => [
								'3.3.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#error-suggestion',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.3.3',
									'title' => "Error Suggestion",
									"message" => "If an input error is automatically detected and suggestions for correction are known, then the suggestions are provided to the user, unless it would jeopardize the security or purpose of the content.",
									'tip' => '',
								],
								'3.3.4' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#error-prevention-legal-financial-data',
									'url' => Plugin::$instance->info["int-quickref"] . '#3.3.4',
									'title' => "Error Prevention (Legal, Financial, Data)",
									"message" => "For Web pages that cause legal commitments or financial transactions for the user to occur, that modify or delete user-controllable data in data storage systems, or that submit user test responses, at least one of the following is true:
										<div class='bullet'><span>Reversible:</span> Submissions are reversible.</div>
										<div class='bullet'><span>Checked:</span> Data entered by the user is checked for input errors and the user is provided an opportunity to correct them.</div>
										<div class='bullet'><span>Confirmed:</span> A mechanism is available for reviewing, confirming, and correcting information before finalizing the submission.</div>",
									'tip' => '',
								],
							]
						]
					],
				]
			),
			array(
				"principle_heading" => "<a href='" . Plugin::$instance->info["ext-quickref"] . '#principle4' . "' target='_blank' title='Principle 4'>Principle 4 - Robust</a>",
				"principle_sub_heading" => "Content must be robust enough that it can be interpreted reliably by a wide variety of user agents, including assistive technologies.",
				"principle_guidelines" => [
					"4.1" => [
						"heading" => "Guideline 4.1 – Compatible",
						"subheading" => "Maximize compatibility with current and future user agents, including assistive technologies.",
						"level" => [
							"A" => [
								'4.1.1' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#parsing',
									'url' => Plugin::$instance->info["int-quickref"] . '#4.1.1',
									'title' => "Parsing",
									"message" => "In content implemented using markup languages, elements have complete start and end tags, elements are nested according to their specifications, elements do not contain duplicate attributes, and any IDs are unique, except where the specifications allow these features.",
									'tip' => '',
								],
								'4.1.2' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#name-role-value',
									'url' => Plugin::$instance->info["int-quickref"] . '#4.1.2',
									'title' => "Name, Role, Value",
									"message" => "For all user interface components (including but not limited to: form elements, links and components generated by scripts), the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.",
									'tip' => '',
								],
							],
							"AA" => [
								'4.1.3' => [
									'ext-url' => Plugin::$instance->info["ext-quickref"] . '#status-messages',
									'url' => Plugin::$instance->info["int-quickref"] . '#4.1.3',
									'title' => "Status Messages",
									"message" => "In content implemented using markup languages, status messages can be programmatically determined through role or properties such that they can be presented to the user by assistive technologies without receiving focus.",
									'tip' => '',
								],
							]
						]
					],

				]
			),
		);

		switch ($level) {
			case 0:
				//Start with Principles
				return $wcag;
				break;
			case 1:
				//Start with Guidelines
				$articles = [];
				foreach ($wcag as $article) {
					foreach ($article["principle_guidelines"] as $key => $guideline) {
						if ($guidelinesOnly) {
							unset($guideline["level"]);
						}
						$articles[$key] = $guideline;
					}
				}
				return $articles;
				break;
			case 2:
				foreach ($wcag as $article) {
					foreach ($article["principle_guidelines"] as $guideline) {
						foreach ($guideline["level"] as $v) {
							foreach ($v as $index => $item) {
								$articles[$index] = $item;
							}
						}
					}
				}
				return $articles;
				break;
		}
	}

	static function verify_security($request){

		if (!is_user_logged_in()) {
			wp_send_json([
				"message" => "No logged in user"
			]);
		}
		if (!isset($request["security"])) {
			wp_send_json([
				"message" => "No nonce detected"
			]);
		}
	
		$verify = wp_verify_nonce( $request["security"], 'oadaas_security_nonce' );
		if(!wp_doing_ajax() || !$verify){
			wp_send_json([
				"message" => "Unauthorized"
			]);
		}
	
	}
}

