<?php
namespace greyd\blocks;

/**
 * Render Conditional Content block.
 *
 * @param array $attributes Block attributes.
 *
 * @return string $block_content
 */
function render_conditional_content_block( $attributes, $block_content ) {

	$url_params = array();
	if ( class_exists( '\Greyd\Extensions\Cookie_Handler' ) ) {
		$url_values = \Greyd\Extensions\Cookie_Handler::get_url_values();
		$cookie_values = \Greyd\Extensions\Cookie_Handler::get_cookie_values();
		$all_url_values = \Greyd\Extensions\Cookie_Handler::get_all_url_values();
		$all_cookie_values = \Greyd\Extensions\Cookie_Handler::get_all_cookie_values();
	} else if ( class_exists('\url_handler') ) {
		$url_values = \url_handler::get_url_values();
		$cookie_values = \url_handler::get_cookie_values();
		$all_url_values = \url_handler::get_all_url_values();
		$all_cookie_values = \url_handler::get_all_cookie_values();
	}

	// get current values
	$values = array(
		'urlparam' => $url_values,
		'cookie'   => $cookie_values,
		'time'     => intval( current_time( 'Hi' ) ), // get hour + minutes as intval (13:15h is 1315, 07:30h is 730)
		'userrole' => is_user_logged_in() ? wp_get_current_user()->roles : array( 'none' ),
	);

	// atts
	// debug( $attributes );
	$operator          = isset( $attributes['operator'] ) ? esc_attr( $attributes['operator'] ) : 'OR';
	$is_displayed      = $operator === 'AND';
	$conditions        = isset( $attributes['conditions'] ) ? (array) $attributes['conditions'] : array();
	$debug             = isset( $attributes['debug'] ) ? (bool) $attributes['debug'] : false;
	$debug_content     = '';
	$default_condition = array(
		'type'     => 'urlparam',
		'operator' => 'is',
		'value'    => '',
		'detail'   => '',
		'custom'   => '',
	);

	// init debug mode
	if ( $debug ) {
		$debug_content = "====== Conditional Content DEBUG Mode ======<br><br>Operator <strong>$operator:</strong> " . (
			$operator === 'AND' ?
			'as soon as 1 condition fails, nothing is rendered.' :
			'as soon as 1 condition matches, the content is rendered.'
		) . '<br><br>Conditions:';
	}

	// get matches
	foreach ( $conditions as $condition ) {

		$is            = null;
		$condition     = array_merge( $default_condition, $condition );
		$type          = $condition['type'];
		$cond_operator = $condition['operator'];
		$should        = $condition['value'];

		if ( $type === 'urlparam' || $type === 'cookie' ) {
			$key = $condition['detail'];

			if ( $key !== 'custom' ) {
				$is = isset( $values[ $type ][ $key ] ) ? esc_attr( $values[ $type ][ $key ] ) : null;
			} else {
				$key     = $condition['custom'];
				$_values = $type === 'urlparam' ? $all_url_values : $all_cookie_values;
				$is      = isset( $_values[ $key ] ) ? esc_attr( $_values[ $key ] ) : null;

				/**
				 * Support for session cookies.
				 * @since 1.7.6
				 */
				if ( $is === null && $type === 'cookie' ) {
					if ( isset( $_SESSION ) && isset( $_SESSION[ $key ] ) ) {
						$is = $_SESSION[ $key ];
					} else if ( isset( $_COOKIE ) && isset( $_COOKIE[ $key ] ) ) {
						$is = $_COOKIE[ $key ];
					}
				}
			}
		}
		elseif ( $type === 'userrole' ) {
			$is = $values[ $type ];
		}
		elseif ( $type === 'time' ) {
			$should = $should === 'custom' ? $condition['custom'] : $should;
			$is     = $values[ $type ];
		}
		elseif ( $type === 'search' ) {
			$should = empty( $cond_operator ) ? 'multiple' : $cond_operator;
			if ( is_search() || is_archive() ) {
				global $wp_query;
				$count = $wp_query->found_posts;
				$is    = $count === 0 ? 'empty' : ( $count === 1 ? 'single' : 'multiple' );
			} else {
				$is = null; }
		}
		elseif ( $type === 'taxonomy' ) {

			global $post;
			$taxonomy = $condition['custom'];

			if ( is_object($post) && isset($post->global_status) && isset($post->post_taxonomy_terms) ) {

				$post_taxonomy_terms = $post->post_taxonomy_terms;

				if ( is_object( $post_taxonomy_terms ) ) {
					$post_taxonomy_terms = (array) $post_taxonomy_terms;
				}

				if ( is_array($post_taxonomy_terms) && isset($post_taxonomy_terms[$taxonomy]) ) {
					foreach ( $post_taxonomy_terms[$taxonomy] as $term ) {
						if ( in_array($term->slug, $should) ) {
							$is = $should;
							break;
						} else {
							$is =  '';
						}
					}
				}
			} else {
				$is = has_term( $should, $taxonomy, $post ) ? $should : '';
			}
		}
		elseif ( $type === 'archivetax' ) {

			$taxonomy = $condition['custom'];
			$is = is_tax( $taxonomy, $should ) ? $should : '';

			if ( empty($is) ) {
				$queried_object = get_queried_object();
				if ( $queried_object && is_a( $queried_object, 'WP_Term' ) && isset( $queried_object->slug ) ) {
					$is = $queried_object->slug;
				}
			}
		}
		elseif ( $type === 'posttype' ) {

			global $post;
			$is = get_post_type( $post );
		}
		elseif ( $type === 'postIndex' ) {

			global $current_post_index;
			if ( $current_post_index ) {
				$is = strval( $current_post_index );
			} else {
				$is = '0';
			}
		}
		elseif ( $type === 'field' ) {
			global $post;
			if ( get_post_type( $post ) == $condition['detail'] ) {
				$fields = \Greyd\Posttypes\Posttype_Helper::get_dynamic_values( $post );
				if ( $fields && is_array($fields) ) {
					if ( isset($fields[$condition['custom']]) ) {
						$is = $fields[$condition['custom']];
					}
				}
			}
		}

		$match = match_condition( $is, $should, $type, $cond_operator );

		if ( $debug ) {
			$debug_content .= sprintf(
				// cookie „utm_medium“ (cookie) HAS_NOT „testvalue“ ==> TRUE (because it is „empty“)
				'<li>%s %s%s? ==> <strong>%s</strong> (because it is %s)',
				$type == 'urlparam' || $type == 'cookie' ? "$type „{$key}“" : ( $type == 'taxonomy' ? "$type „{$taxonomy}“" : $type ), // cookie „utm_medium“
				strtoupper( $cond_operator ), // HAS_NOT
				$cond_operator === 'empty' || $cond_operator === 'not_empty' ? '' : ' „' . ( is_array( $should ) ? implode( ', ', $should ) : $should ) . '“', // eg. „testvalue“
				$match ? 'TRUE' : 'FALSE', // eg. „NO“
				empty( $is ) ? 'empty/not set' : '„' . ( is_array( $is ) ? implode( ', ', $is ) : esc_attr( $is ) ) . '“' // „empty“
			);
		}

		if ( $operator === 'OR' && $match ) {
			$is_displayed = true;
			break;
		} elseif ( $operator === 'AND' && ! $match ) {
			$is_displayed = false;
			break;
		}
	}

	// modify block content
	if ( ! $is_displayed ) {
		$block_content = '';
	}
	if ( ! empty( $debug_content ) ) {
		$block_content = '<pre>' . $debug_content . '</pre>' . $block_content;
	}

	return $block_content;
}


/**
 * Match condition.
 *
 * @param mixed  $is         Current value.
 * @param mixed  $should     What the value should be.
 * @param string $type      Type of the condition
 * @param mixed  $condition  Actual condition.
 *
 * @return bool
 */
function match_condition( $is, $should, $type = 'urlparam', $condition = 'is' ) {
	// USERROLES
	if ( $type === 'userrole' ) {
		$flipped = array_flip( $is ); // get userroles as keys of array
		if ( $condition === 'is' ) {
			return isset( $flipped[ $should ] );
		} elseif ( $condition === 'is_not' ) {
			return ! isset( $flipped[ $should ] );
		}
	}
	// TIME
	elseif ( $type === 'time' ) {
		foreach ( (array) explode( ',', $should ) as $time ) {
			$time = explode( '-', $time ); // explode "start-end" to ["start","end"]
			if ( ! isset( $time[1] ) ) {
				$time[1] = intval( $time[0] ) + 1; // if no end isset -> use start+1 (12 -> 12-13)
			}

			// enable minutes
			foreach ( $time as $i => $t ) {
				$t = strval( $t );
				// convert hour to hour + minutes (13 -> 1300, 08 -> 800, 5 -> 500)
				if ( strpos( $t, ':' ) === false ) {
					$t = str_replace( '0', '', $t ) . '00';
				}
				// convert hour and minutes to string (13:15 -> 1315, 07:1 -> 0710, 9:4 -> 0940)
				else {
					$t = explode( ':', $t );
					if ( isset( $t[1] ) && ! empty( $t[1] ) ) {
						$t[1] = strlen( strval( $t[1] ) ) > 2 ? substr( $t[1], 0, 2 ) : strval( $t[1] ); // max length of 2
						$t[1] = strlen( $t[1] ) < 2 ? '0' + $t[1] : $t[1]; // min length of 2
					} else {
						$t[1] = '00';
					}
					$t = implode( '', $t );
				}
				$time[ $i ] = $t;
			}

			$start_time = $time[0];
			$end_time   = $time[1];

			// debug( "$start_time <= $is" );
			// debug( intval($start_time) <= $is, true );
			// debug( "$is < $end_time" );
			// debug( $is < intval($end_time), true );

			if ( $condition === 'is' ) {
				if ( intval( $start_time ) <= $is && $is < intval( $end_time ) ) {
					return true;
				}
			} elseif ( $condition === 'is_not' ) {
				if ( $is < intval( $start_time ) || intval( $end_time ) <= $is ) {
					return true;
				}
			}
		}
	}
	// SEARCH
	elseif ( $type === 'search' ) {
		return $is === $should;
	}
	// TAXONOMY
	elseif ( $type === 'taxonomy' ) {
		return $condition === 'has_not' ? empty( $is ) : ! empty( $is );
	}
	// default: COOKIE, URL_PARAMS & ARCHIVETAX and other...
	else {
		if ( $condition === 'is' ) {
			return $should === $is;
		} 
		else if ( $condition === 'is_not' ) {
			return $should !== $is;
		} 
		else if ( $condition === 'has' ) {
			return strpos( $is ?: '', strval( $should ) ) !== false;
		} 
		else if ( $condition === 'has_not' ) {
			return strpos( $is ?: '', strval( $should ) ) === false;
		} 
		else if ( $condition === 'empty' ) {
			return empty( $is );
		} 
		else if ( $condition === 'not_empty' ) {
			return ! empty( $is );
		} elseif ( $condition === 'less' ) {
			return intval( $is ) < intval( $should );
		} elseif ( $condition === 'greater' ) {
			return intval( $is ) > intval( $should );
		} elseif ( $condition === 'odd' ) {
			return intval( $is ) % 2 === 1;
		} elseif ( $condition === 'even' ) {
			return intval( $is ) % 2 === 0;
		}
		else if ( $condition === 'less' ) {
			return intval( $is ) < intval( $should );
		}
		else if ( $condition === 'greater' ) {
			return intval( $is ) > intval( $should );
		}
		else if ( $condition === 'odd' ) {
			return intval( $is ) % 2 === 1;
		}
		else if ( $condition === 'even' ) {
			return intval( $is ) % 2 === 0;
		}
	}
	return false;
}
