<?php


class DragBlock_Manage_Fonts_Admin
{
	public function __construct()
	{
		// to support wp_handle_upload
		add_action('init', array($this, 'save_manage_fonts_changes'), 1); // <- High priority to run before the theme.json data is loaded				
		add_action('admin_init', array($this, 'save_google_fonts'));
		add_action('admin_init', array($this, 'save_local_fonts'));
		add_action('admin_menu', array($this, 'create_admin_menu'));
		add_filter('wp_check_filetype_and_ext', array($this, 'wp_check_filetype_and_ext'), 10, 4);
	}

	const ALLOWED_FONT_MIME_TYPES = array(
		'otf'   => 'font/otf',
		'ttf'   => 'font/ttf',
		'woff'  => 'font/woff',
		'woff2' => 'font/woff2'
	);

	// stop here

	public function wp_check_filetype_and_ext($wp_check_filetype_and_ext, $file, $filename, $mimes)
	{
		if (
			!empty($wp_check_filetype_and_ext['ext']) ||
			!empty($wp_check_filetype_and_ext['type']) ||
			!empty($wp_check_filetype_and_ext['proper_filename '])
		) {
			return $wp_check_filetype_and_ext;
		}
		$ext = pathinfo(sanitize_file_name($filename), PATHINFO_EXTENSION);
		if (empty($ext)) {
			return $wp_check_filetype_and_ext;
		}

		$wp_check_filetype_and_ext['ext'] = $ext;
		if (!empty(self::ALLOWED_FONT_MIME_TYPES[$ext])) {
			$wp_check_filetype_and_ext['type'] = self::ALLOWED_FONT_MIME_TYPES[$ext];
		}

		return $wp_check_filetype_and_ext;
	}

	public function has_font_mime_type($file)
	{
		$filetype = wp_check_filetype($file, self::ALLOWED_FONT_MIME_TYPES);
		return in_array($filetype['type'], self::ALLOWED_FONT_MIME_TYPES, true);
	}


	public function create_admin_menu()
	{
		if (!wp_is_block_theme()) {
			return;
		}

		// $manage_fonts_page_title = _x('Font Library', 'UI String', 'dragblock');
		// $manage_fonts_menu_title = $manage_fonts_page_title;
		// add_theme_page( $manage_fonts_page_title, $manage_fonts_menu_title, 'edit_theme_options', 'manage-fonts', array( 'DragBlock_Fonts_Page', 'manage_fonts_admin_page' ) );

		add_submenu_page(
			DRAGBLOCK_ADMIN_MENU_SLUG,
			_x('Font Library', 'UI String', 'dragblock'), // title
			_x('Font Library', 'UI String', 'dragblock'), // menu
			'edit_theme_options',
			DRAGBLOCK_FONT_LIB_SLUG,
			array('DragBlock_Fonts_Page', 'manage_fonts_admin_page')
		);

		add_submenu_page(
			DRAGBLOCK_FONT_LIB_SLUG . '-google-font',
			_x('Embed Google font in the site editor', 'UI String', 'dragblock'),  // title
			_x('Embed Google Font', 'UI String', 'dragblock'), // menu
			'edit_theme_options',
			'dragblock-add-google-fonts',
			array('DragBlock_Google_Fonts', 'google_fonts_admin_page')
		);


		add_submenu_page(
			DRAGBLOCK_FONT_LIB_SLUG . '-local-font',
			_x('Embed local font in the site editor', 'UI String', 'dragblock'), // title
			_x('Embed local font', 'UI String', 'dragblock'), // menu
			'edit_theme_options',
			'dragblock-add-local-fonts',
			array('DragBlock_Local_Fonts', 'local_fonts_admin_page')
		);
	}

	public function has_file_and_user_permissions()
	{
		$has_user_permissions = $this->user_can_edit_themes();
		$has_file_permissions = $this->can_read_and_write_font_assets_directory();
		return $has_user_permissions && $has_file_permissions;
	}

	public function user_can_edit_themes()
	{
		if (defined('DISALLOW_FILE_EDIT') && true === DISALLOW_FILE_EDIT) {
			add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_file_edit_error'));
			return false;
		}

		if (!current_user_can('edit_themes')) {
			add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_user_cant_edit_theme'));
			return false;
		}
		return true;
	}

	public function can_read_and_write_font_assets_directory()
	{
		// Create the font assets folder if it doesn't exist
		$temp_dir         = get_temp_dir();
		// $font_assets_path = get_stylesheet_directory() . '/assets/fonts/';
		// we chose upload directory to allow backup plugins to backup our files as well		
		$font_assets_path = DRAGBLOCK_UPLOAD_DIR . '/fonts/';
		if (!is_dir($font_assets_path)) {
			// @fixme: check if created folder before working
			wp_mkdir_p($font_assets_path);
		}
		// If the font asset folder can't be written return an error
		if (!wp_is_writable($font_assets_path) || !is_readable($font_assets_path) || !wp_is_writable($temp_dir)) {
			add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_manage_fonts_permission_error'));
			return false;
		}
		return true;
	}

	/**
	 * WordPress loads global styles via REST API
	 * $active_global_styles_id = WP_Theme_JSON_Resolver::get_user_global_styles_post_id(); >> get_user_data_from_wp_global_styles 
	 * So we have to refresh the global styles post inorder to show updated fonts
	 */
	public function refresh_global_styles()
	{
		$user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles(wp_get_theme(), true);
		if (empty($user_cpt) || empty($user_cpt['ID']) || empty($user_cpt['post_content'])) {
			return;
		}

		// Assuming $post_content contains your JSON string
		$theme_json = json_decode($user_cpt['post_content'], true);
		$theme_json = dragblock_default_theme_json_font_lib($theme_json);		

		// Update the post using wp_update_post
		wp_update_post(array(
			'ID'           => $user_cpt['ID'],
			'post_content' => json_encode($theme_json), // Set the modified JSON as the new post content
		));
	}

	public function delete_font_asset($font_face)
	{
		// if the font asset is a theme asset, delete it
		$font_path    = str_replace(WP_CONTENT_URL, WP_CONTENT_DIR, $font_face['src'][0]);

		if (file_exists($font_path) && unlink($font_path)) {
			return true;
		}

		return add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_font_asset_removal_error'));
	}

	protected function prepare_font_families_for_database($font_families)
	{
		$prepared_font_families = array();

		foreach ($font_families as $font_family) {
			if (isset($font_family['fontFace'])) {
				$new_font_faces = array();
				foreach ($font_family['fontFace'] as $font_face) {
					$updated_font_face = $font_face;
					// Remove font license from readme.txt if font family is removed
					// if (isset($font_family['shouldBeRemoved'])) {
					// 	$this->manage_font_license($font_face['fontFamily'], 'remove');
					// }
					if (!isset($font_face['shouldBeRemoved']) && !isset($font_family['shouldBeRemoved'])) {
						$new_font_faces[] = $updated_font_face;
					} else {
						$this->delete_font_asset($font_face);
					}
				}

				$font_family['fontFace'] = $new_font_faces;
			}
			if (!isset($font_family['shouldBeRemoved'])) {
				$prepared_font_families[] = $font_family;
			}
		}

		return $prepared_font_families;
	}

	public function save_manage_fonts_changes()
	{
		if (
			!empty($_POST['nonce']) &&
			wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'dragblock_font_library') &&
			!empty($_POST['dragblock-font-library-new-font-json']) &&
			$this->has_file_and_user_permissions()
		) {
			// parse json from form
			// $new_font_json = json_decode(stripslashes($_POST['dragblock-font-library-new-font-json']), true);
			$new_font_json = json_decode(sanitize_text_field(wp_unslash($_POST['dragblock-font-library-new-font-json'])), true);
			if (empty($new_font_json)) {
				// cannot decode font_json
				return;
			}
			$new_font_families    = $this->prepare_font_families_for_database($new_font_json);

			$this->replace_all_font_families($new_font_families);
			// delete cache to refresh font_families
			// wp_cache_delete('wp_get_global_settings_custom', 'theme_json');
			$this->refresh_global_styles();
			add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_delete_font_success'));
		}
	}

	public function save_local_fonts()
	{

		if (
			!empty($_POST['nonce']) &&
			wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'dragblock_font_library') &&
			!empty($_FILES['font-file']) &&
			!empty($_POST['font-name']) &&
			!empty($_POST['font-weight']) &&
			!empty($_POST['font-style']) &&
			$this->has_file_and_user_permissions()
		) {

			if (
				!empty($_FILES) &&
				isset($_FILES['font-file']) &&
				isset($_FILES['font-file']['name']) &&
				$this->has_font_mime_type(sanitize_file_name($_FILES['font-file']['name']))
			) {
				$font_slug = sanitize_title(wp_unslash($_POST['font-name']));
				$font_style = sanitize_text_field(wp_unslash($_POST['font-style']));
				$font_weight = sanitize_text_field(wp_unslash($_POST['font-weight']));
				$font_name = sanitize_text_field(wp_unslash($_POST['font-name']));
				$file_extension = pathinfo(sanitize_file_name(wp_unslash($_FILES['font-file']['name'])), PATHINFO_EXTENSION);
				$file_name = $font_slug . '_' . $font_style . '_' . $font_weight . '.' . $file_extension;
				$font_assets_path = DRAGBLOCK_UPLOAD_DIR . '/fonts/';
				$file_path = $font_assets_path . $file_name;

				// move_uploaded_file(sanitize_file_name($_FILES['font-file']['tmp_name']), $file_path);
				$upload_overrides = array(
					'test_form' => false,
					'mines' => self::ALLOWED_FONT_MIME_TYPES
				);


				$file_info = wp_handle_upload($_FILES['font-file'], $upload_overrides);

				if (isset($file_info['error'])) {
					return add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_embed_font_file_error'));
				}


				// Use the `rename()` function to move the file from the temporary location to the desired destination
				if (!rename($file_info['file'], $file_path)) {
					return add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_embed_font_file_error'));
				}

				$uploaded_font_face = array(
					'fontFamily' => $font_name,
					'fontWeight' => $font_weight,
					'fontStyle'  => $font_style,
					'src'        => array(
						// 'file:./' . $file_name,
						DRAGBLOCK_UPLOAD_URL . '/fonts/' . $file_name,
						// $file_path,
					),
				);

				if (!empty($_POST['font-variation-settings'])) {
					// replace escaped single quotes with single quotes
					$font_variation_settings = sanitize_text_field(wp_unslash($_POST['font-variation-settings']));
					$uploaded_font_face['fontVariationSettings'] = $font_variation_settings;
				}

				$new_font_faces = array($uploaded_font_face);

				$this->add_or_update_font_faces($font_name, $font_slug, $new_font_faces);

				// Add font license to readme.txt
				// $this->manage_font_license($font_name, $file_name);
				// delete cache to refresh font_families
				// wp_cache_delete('wp_get_global_settings_custom', 'theme_json');
				$this->refresh_global_styles();
				return add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_embed_font_success'));
			}

			return add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_embed_font_file_error'));
		}
	}

	public function get_font_slug($name)
	{
		$slug = sanitize_title($name);
		$slug = preg_replace('/\s+/', '', $slug); // Remove spaces
		return $slug;
	}

	public function save_google_fonts()
	{
		if (
			!empty($_POST['nonce']) &&
			wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['nonce'])), 'dragblock_font_library') &&
			!empty($_POST['selection-data']) &&
			$this->has_file_and_user_permissions()
		) {
			// Gets data from the form
			$data = json_decode(sanitize_text_field(wp_unslash($_POST['selection-data'])), true);
			if (empty($data)) {
				return;
			}

			foreach ($data as $font_family) {
				$google_font_name = $font_family['family'];
				$font_slug        = $this->get_font_slug($google_font_name);
				$variants         = $font_family['faces'];
				$new_font_faces   = array();
				foreach ($variants as $variant) {
					// variant name is $variant_and_url[0] and font asset url is $variant_and_url[1]
					$file_extension = pathinfo($variant['src'], PATHINFO_EXTENSION);
					$file_name      = $font_slug . '_' . $variant['style'] . '_' . $variant['weight'] . '.' . $file_extension;

					// Download font asset in temp folder
					$temp_file = download_url($variant['src']);

					if ($this->has_font_mime_type($variant['src'])) {

						// Move font asset to theme assets folder
						// rename($temp_file, get_stylesheet_directory() . '/assets/fonts/' . $file_name);
						rename($temp_file, DRAGBLOCK_UPLOAD_DIR . '/fonts/' . $file_name);

						// Add each variant as one font face
						$new_font_faces[] = array(
							'fontFamily' => $google_font_name,
							'fontStyle'  => $variant['style'],
							'fontWeight' => $variant['weight'],
							'src'        => array(
								// we use the full path so we don't worry about path 
								// when we want to change the place to save our files
								// 'file:./' . $file_name,
								DRAGBLOCK_UPLOAD_URL . '/fonts/' . $file_name,

								// *** YOU CANNOT DO THIS AT THIS TIME ***
								// BECAUSE WORDPRESS WILL PICK THE LAST URL IN THE 'SRC'
								// TO SHOW AS THE URL OF THE FONT
								// fall back to Google fonts incase the file is not available
								// $variant['src']
							),
						);
					}
				}

				$this->add_or_update_font_faces($google_font_name, $font_slug, $new_font_faces);

				// Add font license to readme.txt
				// $this->manage_font_license($font_family['family'], $file_name);
			}
			// delete cache to refresh font_families
			// wp_cache_delete('wp_get_global_settings_custom', 'theme_json');
			$this->refresh_global_styles();
			add_action('admin_notices', array('DragBlock_Font_Form_Messages', 'admin_notice_embed_font_success'));
		}
	}

	/**
	 * 
	 */
	public function replace_all_font_families($font_families)
	{
		// We need to save to the database so we can define later instead of saving to theme json which will be removed when updating theme 
		update_option(DRAGBLOCK_FONT_LIB_SLUG, $font_families);
	}

	public function add_or_update_font_faces($font_name, $font_slug, $font_faces)
	{
		$font_families = get_option(DRAGBLOCK_FONT_LIB_SLUG, array());
		$font_families[] = array(
			'fontFamily' => $font_name,
			'slug'       => $font_slug,
			'fontFace'   => $font_faces,
		);

		update_option(DRAGBLOCK_FONT_LIB_SLUG, $font_families);
	}

	/**
	 * to minimize the initial release, 
	 * we cleaned this and will develop later
	 */
	// function manage_font_license($font_name, $file_name)
	// {
	// }
}

$dragblock_manage_fonts_admin = new DragBlock_Manage_Fonts_Admin();
