<?php //phpcs:ignore
/**
 * VK_Helpers
 *
 * @package vektor-inc/vk-helpers
 * @license GPL-2.0+
 *
 * @version 0.2.1
 */

namespace VektorInc\VK_Helpers;

/**
 * VK_Helpers
 */
class VkHelpers {

	/**
	 * Constructor
	 */
	private function __construct() {
		// Composer版じゃない古い VK_Helpers が既にある場合はエイリアスを作成しない.
		if ( class_exists( 'VK_Helpers' ) ) {
			return;
		}

		// Composer版じゃない古い VK_Helpers が使用されている場所でも動作するようにエイリアスを作成.
		class_alias( '\VektorInc\VK_Helpers\VkHelpers', '\VK_Helpers' );
	}

	/*
	get_post_top_info
	get_post_type_info
	sanitize_checkbox
	sanitize_number_percentage
	sanitize_choice
	sanitize_textarea
	sanitize_boolean
	color_auto_modifi
	color_adjust_under_ff
	color_mode_check
	color_convert_rgba
	deactivate_plugin
	*/

	// public function __construct() {
	// add_action( 'customize_register', array( __CLASS__, 'add_customize_class' ), 0 );
	// }

	// public static function add_customize_class( $wp_customize ) {
	// if ( ! class_exists( 'VK_Custom_Html_Control' ) ) {
	// require_once dirname( __FILE__ ) . '/class-vk-custom-html-control.php';
	// }
	// if ( ! class_exists( 'VK_Custom_Text_Control' ) ) {
	// require_once dirname( __FILE__ ) . '/class-vk-custom-text-control.php';
	// }
	// }

	/**
	 * Get post top page info
	 *
	 * @return array{
	 *   id: string | int,
	 *   use: bool,
	 *   name: string
	 * } $post_top_info
	 */
	public static function get_post_top_info() {

		$post_top_info = array();

		// Get post top page by setting display page.
		$post_top_info['id'] = get_option( 'page_for_posts' );

		// Set use post top page flag.
		$post_top_info['use'] = ( $post_top_info['id'] ) ? true : false;

		// When use post top page that get post top page name.
		$post_top_info['name'] = ( $post_top_info['use'] ) ? get_the_title( $post_top_info['id'] ) : '';

		$post_top_info['url'] = ( $post_top_info['use'] ) ? get_permalink( $post_top_info['id'] ) : '';

		return $post_top_info;
	}


	/**
	 * Get post type info
	 *
	 * @return array{
	 *   slug: string,
	 *   name: string,
	 *   url: string
	 * } $post_type_info
	 */
	public static function get_post_type_info() {
		// Check use post top page.
		$post_top_info = self::get_post_top_info();

		$woocommerce_shop_page_id = get_option( 'woocommerce_shop_page_id' );

		// Get post type slug.
		// When WooCommerce taxonomy archive page , get_post_type() is does not work properly.

		global $wp_query;
		global $post;

		// ブロックエディタで投稿タイプを取得するために最初に global $post->post_type から取得
		// これによりループ内でも該当の投稿の投稿タイプを取得するようになった
		if ( ! empty( $post->post_type ) ) {
			$post_type_info['slug'] = $post->post_type;
		// is_page() は編集画面で正しく動作しない（まぁ正しく動作しなくてもいいんですけど...）のと、
		// 固定ページはタクソノミーアーカイブなども基本存在しないので get_post_type() を使用する.
		} else if ( 'page' === get_post_type() ) {
			$post_type_info['slug'] = 'page';
		} elseif ( ! empty( $wp_query->query_vars['post_type'] ) ) {

			$post_type_info['slug'] = $wp_query->query_vars['post_type'];
			// Maybe $wp_query->query_vars['post_type'] is usually an array...
			if ( is_array( $post_type_info['slug'] ) ) {
				$post_type_info['slug'] = current( $post_type_info['slug'] );
			}
		} elseif ( is_tax() ) {
			// Case of tax archive and no posts.
			$taxonomy               = get_queried_object()->taxonomy;
			$post_type_info['slug'] = get_taxonomy( $taxonomy )->object_type[0];
		} else {
			// This is necessary that when no posts.
			$post_type_info['slug'] = 'post';
		}

		// Get custom post type name.
		/*-------------------------------------------*/
		$post_type_object = get_post_type_object( $post_type_info['slug'] );
		if ( $post_type_object ) {
			$allowed_html = array(
				'span' => array( 'class' => array() ),
				'b'    => array(),
			);
			if ( $post_top_info['use'] && 'post' === $post_type_info['slug'] ) {
				$post_type_info['name'] = wp_kses( get_the_title( $post_top_info['id'] ), $allowed_html );
			} elseif ( $woocommerce_shop_page_id && 'product' === $post_type_info['slug'] ) {
				$post_type_info['name'] = wp_kses( get_the_title( $woocommerce_shop_page_id ), $allowed_html );
			} else {
				$post_type_info['name'] = esc_html( $post_type_object->labels->name );
			}
		}

		// Get custom post type archive url.
		/*-------------------------------------------*/
		if ( $post_top_info['use'] && 'post' === $post_type_info['slug'] ) {
			$post_type_info['url'] = esc_url( get_the_permalink( $post_top_info['id'] ) );
		} elseif ( $woocommerce_shop_page_id && 'product' === $post_type_info['slug'] ) {
			$post_type_info['url'] = esc_url( get_the_permalink( $woocommerce_shop_page_id ) );
		} else {
			$post_type_info['url'] = esc_url( get_post_type_archive_link( $post_type_info['slug'] ) );
		}

		$post_type_info = apply_filters( 'vk_get_post_type_info', $post_type_info );
		return $post_type_info;
	}

	/**
	 * Get Post Taxonomies
	 *
	 * @param int   $post_id : post id.
	 * @param array $args : tax onomies args.
	 * @return array $taxonomies
	 */
	public static function get_display_taxonomies( $post_id = null, $args = null ) {
		if ( ! $post_id ) {
			global $post;
			$post_id = $post->ID;
		}
		$taxonomies = get_the_taxonomies( $post_id, $args );

		// 非公開のタクソノミーを自動的に除外.
		foreach ( $taxonomies as $taxonomy => $value ) {
			$taxonomy_info = get_taxonomy( $taxonomy );
			if ( empty( $taxonomy_info->public ) ) {
				unset( $taxonomies[ $taxonomy ] );
			}
		}

		// 上記を後で実装したので以下の処理は事実上不要と思われるが、
		// 公開タクソノミーで意図的に表示したくないものもあるかもしれないのでフィルターは消さない.
		$exclusion = array( 'post_tag', 'product_type' );
		$exclusion = apply_filters( 'vk_get_display_taxonomies_exclusion', $exclusion );
		if ( is_array( $exclusion ) ) {
			foreach ( $exclusion as $key => $value ) {
				unset( $taxonomies[ $value ] );
			}
		}
		return $taxonomies;
	}

	/**
	 * Sanitize Check Box
	 *
	 * @param string $input $input.
	 */
	public static function sanitize_checkbox( $input ) {
		if ( 'true' === $input || true === $input ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Sanitize Number
	 *
	 * @param string $input $input.
	 */
	public static function sanitize_number( $input ) {
		$input = mb_convert_kana( $input, 'a' );
		if ( is_numeric( $input ) ) {
			return $input;
		} else {
			return 0;
		}
	}

	/**
	 * Sanitize Number Percentage
	 *
	 * @param string $input $input.
	 */
	public static function sanitize_number_percentage( $input ) {
		$input = self::sanitize_number( $input );
		if ( 0 <= $input && $input <= 100 ) {
			return $input;
		} else {
			return 0;
		}
	}

	/**
	 * Sanitize Choice
	 *
	 * @param string $input $input.
	 */
	public static function sanitize_choice( $input ) {
		return esc_attr( $input );
	}


	/**
	 * Sanitize Text Area
	 *
	 * @param string $input $input.
	 */
	public static function sanitize_textarea( $input ) {
		$allowed_html = array(
			'a'      => array(
				'id'    => array(),
				'href'  => array(),
				'title' => array(),
				'class' => array(),
				'role'  => array(),
			),
			'br'     => array(),
			'em'     => array(),
			'strong' => array(),
			'i'      => array(
				'class' => array(),
			),
		);
		return wp_kses( $input, $allowed_html );
	}

	/**
	 * Sanitize Boolean
	 *
	 * @param string $input $input.
	 */
	public static function sanitize_boolean( $input ) {
		if ( true === $input ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * [ 非推奨 ] 色を比率で明るくしたり暗くする
	 * 既にCSSのfilterなどでなどで同じような事ができるため非推奨
	 *
	 * @param  string  $color       #あり16進数.
	 * @param  integer $change_rate 1 が 100%.
	 */
	public static function color_auto_modifi( $color, $change_rate = 1 ) {

		if ( ! $color ) {
			return;
		}

		$color = preg_replace( '/#/', '', $color );
		// 16進数を10進数に変換
		$r = hexdec( substr( $color, 0, 2 ) );
		$g = hexdec( substr( $color, 2, 2 ) );
		$b = hexdec( substr( $color, 4, 2 ) );

		$color_array = array();
		// 10進数の状態で変更レートを掛けて16進数で受け取る.
		$color_array['r'] = self::color_auto_modifi_single( $r, $change_rate );
		$color_array['g'] = self::color_auto_modifi_single( $g, $change_rate );
		$color_array['b'] = self::color_auto_modifi_single( $b, $change_rate );

		$new_color = '#';

		foreach ( $color_array as $key => $value ) {
			$new_color .= $color_array[ $key ];
		}
		return $new_color;
	}

	/**
	 * [ 非推奨 ] RGBの個別の色をレートで変換して16進数で返す
	 * color_auto_modifi でのみ使用されている
	 *
	 * @param  string  $color_num : RGBの単色の10進数の数値.
	 * @param  integer $change_rate : 1 が 100%.
	 * @return string $color : RGBの単色の16進数の数値.
	 */
	public static function color_auto_modifi_single( $color_num, $change_rate = 1 ) {

		$color_num = $color_num * $change_rate;
		if ( $color_num >= 255 ) {
			$color_num = 255;
		}

		// レートをかけて四捨五入.
		$rounded = round( $color_num );

		// 結果を16進数に変換.
		$hex = dechex( $rounded );

		// 結果がもし1桁なら2桁になるように0で埋める.
		$color = str_pad( $hex, 2, '0', STR_PAD_LEFT );

		return $color;
	}

	/**
	 * [color_mode_check description]
	 *
	 * @param string $input input color code.
	 */
	public static function color_mode_check( $input = '#ffffff' ) {
		$color['input'] = $input;
		// delete #.
		$color['input'] = preg_replace( '/#/', '', $color['input'] );

		$color_len = strlen( $color['input'] );

		// Only 3 character.
		if ( 3 === $color_len ) {
			$color_red   = substr( $color['input'], 0, 1 ) . substr( $color['input'], 0, 1 );
			$color_green = substr( $color['input'], 1, 1 ) . substr( $color['input'], 1, 1 );
			$color_blue  = substr( $color['input'], 2, 1 ) . substr( $color['input'], 2, 1 );
		} elseif ( 6 === $color_len ) {
			$color_red   = substr( $color['input'], 0, 2 );
			$color_green = substr( $color['input'], 2, 2 );
			$color_blue  = substr( $color['input'], 4, 2 );
		} else {
			$color_red   = 'ff';
			$color_green = 'ff';
			$color_blue  = 'ff';
		}

		// change 16 to 10 number.
		$color['color_red']   = hexdec( $color_red );
		$color['color_green'] = hexdec( $color_green );
		$color['color_blue']  = hexdec( $color_blue );

		$color['number_sum'] = $color['color_red'] + $color['color_green'] + $color['color_blue'];

		$color['brightness'] = 0.00130718954 * $color['number_sum'];

		if ( $color['brightness'] < 0.5 ) {
			$color['mode'] = 'dark';
		} else {
			$color['mode'] = 'bright';
		}

		return $color;

	}

	/**
	 * 16進数をRGBAに変換する
	 *
	 * @param  string $input hex color code.
	 * @param  num    $alpha transparnt value.
	 */
	public static function color_convert_rgba( $input = '#FFFFFF', $alpha = 1 ) {
		$color = self::color_mode_check( $input );
		$rgba .= 'rgba(' . $color['color_red'] . ', ' . $color['color_green'] . ', ' . $color['color_blue'] . ', ' . $alpha . ')';
		return esc_html( $rgba );
	}

	/**
	 * 有効化されているプラグインを無効化する
	 *
	 * @param string $plugin_path path of plugin.
	 */
	public static function deactivate_plugin( $plugin_path ) {
		include_once ABSPATH . 'wp-admin/includes/plugin.php';
		if ( is_plugin_active( $plugin_path ) ) {
			$active_plugins = get_option( 'active_plugins' );
			// delete item.
			$active_plugins = array_diff( $active_plugins, array( $plugin_path ) );
			// re index.
			$active_plugins = array_values( $active_plugins );
			update_option( 'active_plugins', $active_plugins );
		}
	}

}
