<?php
/**
 * Plugin Name: Ultimate FAQ Solution
 * Description: This file contains the custom post type and related functionality for managing FAQs.
 * Author: Your Name
 * Version: 1.0
 *
 * @package UltimateFAQSolution
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
/**
 * Register the custom post type for FAQs.
 *
 * This function registers a custom post type called 'ufaqsw' for managing FAQs.
 * It sets up labels, arguments, and other properties for the post type.
 */
function ufaqsw_register_cpt() {

	$ufaqsw_list_labels = array(
		'name'               => __( 'FAQ Groups', 'ufaqsw' ),
		'singular_name'      => __( 'FAQ Group', 'ufaqsw' ),
		'add_new'            => __( 'New FAQ Group', 'ufaqsw' ),
		'add_new_item'       => __( 'Add New FAQ Group', 'ufaqsw' ),
		'edit_item'          => __( 'Edit FAQ Group', 'ufaqsw' ),
		'new_item'           => __( 'New FAQ Group', 'ufaqsw' ),
		'all_items'          => __( 'All FAQ Groups', 'ufaqsw' ),
		'view_item'          => __( 'View FAQ Group', 'ufaqsw' ),
		'search_items'       => __( 'Search FAQ Group', 'ufaqsw' ),
		'not_found'          => __( 'No FAQ Group found', 'ufaqsw' ),
		'not_found_in_trash' => __( 'No FAQ Group found in the Trash', 'ufaqsw' ),
		'parent_item_colon'  => '',
		'menu_name'          => __( 'Ultimate FAQs', 'ufaqsw' ),

	);

	$ufaqsw_list_args = array(
		'labels'              => $ufaqsw_list_labels,
		'description'         => __( 'This post type holds all FAQs for your site.', 'ufaqsw' ),
		'menu_position'       => 25,
		'exclude_from_search' => true,
		'show_in_nav_menus'   => false,
		'supports'            => array( 'title', 'author' ), // Added 'author' support.
		'has_archive'         => false,
		'public'              => false,  // it's not public, it shouldn't have its own permalink, and so on.
		'publicly_queryable'  => false,  // you should be able to query it.
		'show_ui'             => true,  // you should be able to edit it in wp-admin.
		'can_export'          => true,  // you should be able to export it.
		'menu_icon'           => 'dashicons-editor-help',
		'show_in_rest'        => true,  // Enable support for the REST API.
		'rest_base'           => 'ufaqsw', // Optional custom REST API base slug.
		'rewrite'             => false,
	);

	if ( 'on' === get_option( 'ufaqsw_enable_group_detail_page' ) ) {
		$ufaqsw_list_args['public']             = true;
		$ufaqsw_list_args['publicly_queryable'] = true;
		$ufaqsw_list_args['capability_type']    = 'post';
		$ufaqsw_list_args['rewrite']            = array( 'slug' => ( get_option( 'ufaqsw_detail_page_slug' ) ? get_option( 'ufaqsw_detail_page_slug' ) : 'faq-group' ) );
	}

	register_post_type( 'ufaqsw', $ufaqsw_list_args );

	// FAQ Appearance Custom Post Type.
	$labels = array(
		'name'               => __( 'Appearances', 'ufaqsw' ),
		'singular_name'      => __( 'Appearance', 'ufaqsw' ),
		'menu_name'          => __( 'Appearances', 'ufaqsw' ),
		'name_admin_bar'     => __( 'Appearance', 'ufaqsw' ),
		'add_new'            => __( 'Add New', 'ufaqsw' ),
		'add_new_item'       => __( 'Add New Appearance', 'ufaqsw' ),
		'new_item'           => __( 'New Appearance', 'ufaqsw' ),
		'edit_item'          => __( 'Edit Appearance', 'ufaqsw' ),
		'view_item'          => __( 'View Appearance', 'ufaqsw' ),
		'all_items'          => __( 'All Appearances', 'ufaqsw' ),
		'search_items'       => __( 'Search Appearances', 'ufaqsw' ),
		'not_found'          => __( 'No appearances found.', 'ufaqsw' ),
		'not_found_in_trash' => __( 'No appearances found in Trash.', 'ufaqsw' ),
	);

	$args = array(
		'labels'             => $labels,
		'public'             => false, // Not public-facing.
		'show_ui'            => true,  // Show in admin.
		'show_in_menu'       => false, // We'll manually add it under FAQ Group.
		'capability_type'    => 'post',
		'hierarchical'       => false,
		'supports'           => array( 'title' ),
		'menu_position'      => null,
		'menu_icon'          => 'dashicons-admin-customizer',
	);

	register_post_type( 'ufaqsw_appearance', $args );
}
add_action( 'init', 'ufaqsw_register_cpt' );

add_action( 'cmb2_admin_init', 'ufaqsw_register_description_field_metabox' );

/**
 * Registers a metabox for the FAQ group description for the 'ufaqsw' post type.
 */
function ufaqsw_register_description_field_metabox() {

	$cmb_group = new_cmb2_box(
		array(
			'id'           => 'ufaqsw_faq_meta',
			'title'        => esc_html__( 'Group Description', 'ufaqsw' ),
			'object_types' => array( 'ufaqsw' ),
			'closed'       => true, // Collapse by default.
		)
	);

	$cmb_group->add_field(
		array(
			'name' => '',
			'desc' => esc_html__( 'Note: This section is visible only in the FAQ Assistant window and FAQ Group detail page if enabled.', 'ufaqsw' ),
			'type' => 'title',
			'id'   => 'description_meta_title',
		)
	);

	$cmb_group->add_field(
		array(
			'name'    => esc_html__( 'Short Description', 'ufaqsw' ),
			'desc'    => esc_html__( 'Write a short description about the FAQ group. This will only be displayed in the FAQ assistant window at this moment.', 'ufaqsw' ),
			'id'      => 'group_short_desc',
			'type'    => 'wysiwyg',
			'options' => array(
				'textarea_rows' => 5,
			),
		)
	);
}

add_action( 'cmb2_admin_init', 'ufaqsw_register_repeatable_group_field_metabox' );
/**
 * Registers a repeatable group field metabox for the custom post type 'ufaqsw'.
 *
 * This function adds a metabox to manage FAQs within a group, allowing users to add,
 * edit, and remove FAQ entries with fields for questions and answers.
 */
function ufaqsw_register_repeatable_group_field_metabox() {

	$cmb_group = new_cmb2_box(
		array(
			'id'           => 'ufaqsw_faq_items',
			'title'        => esc_html__( 'FAQs', 'ufaqsw' ),
			'object_types' => array( 'ufaqsw' ),
		)
	);

	$group_field_id = $cmb_group->add_field(
		array(
			'id'          => 'ufaqsw_faq_item01',
			'type'        => 'group',
			'description' => esc_html__( 'Add FAQ to this group by click on "Add FAQ Entry" Button', 'ufaqsw' ),
			'options'     => array(
				'group_title'    => esc_html__( 'FAQ {#}', 'ufaqsw' ), // {#} gets replaced by row number.
				'add_button'     => esc_html__( 'Add FAQ Entry', 'ufaqsw' ),
				'remove_button'  => esc_html__( 'Remove FAQ Entry', 'ufaqsw' ),
				'sortable'       => true,
				'closed'         => false, // true to have the groups closed by default.
				'remove_confirm' => esc_html__( 'Are you sure you want to remove the FAQ entry?', 'ufaqsw' ),
			),
		)
	);

	$cmb_group->add_group_field(
		$group_field_id,
		array(
			'name' => esc_html__( 'Question', 'ufaqsw' ),
			'id'   => 'ufaqsw_faq_question',
			'desc' => esc_html__( 'Write Your Question', 'ufaqsw' ),
			'type' => 'text_html',
		)
	);

	$cmb_group->add_group_field(
		$group_field_id,
		array(
			'name'    => esc_html__( 'Answer', 'ufaqsw' ),
			'desc'    => esc_html__( 'Write Your Answer', 'ufaqsw' ),
			'id'      => 'ufaqsw_faq_answer',
			'type'    => 'wysiwyg',
			'options' => array(
				'textarea_rows' => 5,
			),
		)
	);
}

/**
 * Modifies the columns displayed in the admin list table for the 'ufaqsw' post type.
 *
 * @param array $defaults The default columns.
 * @return array Modified columns with additional custom columns.
 */
function ufaqsw_faq_columns_head( $defaults ) {

	$new_columns = array();

	$new_columns['cb']                     = '<input type="checkbox" />';
	$new_columns['title']                  = __( 'Title', 'ufaqsw' );
	$new_columns['ufaqsw_item_count']      = __( 'Number of FAQs', 'ufaqsw' );
	$new_columns['ufaqsw_item_appearance'] = __( 'Appearance', 'ufaqsw' );
	$new_columns['shortcode_col']          = __( 'Shortcode', 'ufaqsw' );
	$new_columns['date']                   = __( 'Date', 'ufaqsw' );
	return $new_columns;
}

/**
 * Outputs custom column content for the 'ufaqsw' post type in the admin list table.
 *
 * @param string $column_name The name of the column to display content for.
 * @param int    $post_ID     The ID of the current post.
 */
function ufaqsw_faq_columns_content( $column_name, $post_ID ) {

	if ( 'ufaqsw_item_count' === $column_name ) {
		$faqs = get_post_meta( $post_ID, 'ufaqsw_faq_item01' );
		echo count( isset( $faqs[0] ) && is_array( $faqs[0] ) ? $faqs[0] : array() );
	}
	if ( 'shortcode_col' === $column_name ) {
		echo '<input type="text" value="[ufaqsw id=' . esc_attr( $post_ID ) . ']" class="ufaqsw_admin_faq_shorcode_copy" />';
	}

	if ( 'ufaqsw_item_appearance' === $column_name ) {

		$appearance = ufaqsw_get_appearance_id( $post_ID );

		if ( ! empty( $appearance ) ) {
			$edit_link = get_edit_post_link( $appearance );
			echo '<a href="' . esc_url( $edit_link ) . '" title="' . esc_html__( 'Edit Appearance', 'ufaqsw' ) . '" >' . esc_html( get_the_title( $appearance ) ) . '</a>';
		}
	}
}

add_filter( 'manage_ufaqsw_posts_columns', 'ufaqsw_faq_columns_head' );
add_action( 'manage_ufaqsw_posts_custom_column', 'ufaqsw_faq_columns_content', 10, 2 );

/**
 * Duplicates a post as a draft for the custom post type 'ufaqsw'.
 *
 * This function handles duplicating a post, including its metadata and terms,
 * and redirects the user to the edit screen of the duplicated post.
 */
function ufaqsw_rd_duplicate_post_as_draft() {
	global $wpdb;
	if ( ! ( isset( $_GET['post'] ) || isset( $_POST['post'] ) || ( isset( $_REQUEST['action'] ) && 'rd_duplicate_post_as_draft' === $_REQUEST['action'] ) ) ) {
		wp_die( 'No post to duplicate has been supplied!' );
	}

	/*
	 * Nonce verification
	 */
	if ( ! isset( $_GET['duplicate_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['duplicate_nonce'] ) ), basename( __FILE__ ) ) ) {
		return;
	}

	/*
	 * get the original post id
	 */
	$post_id = ( isset( $_GET['post'] ) ? absint( $_GET['post'] ) : absint( $_POST['post'] ) );

	/*
	 * and all the original post data then
	 */
	$post = get_post( $post_id );

	/*
	 * if you don't want current user to be the new post author,
	 * then change next couple of lines to this: $new_post_author = $post->post_author;
	 */
	$current_user    = wp_get_current_user();
	$new_post_author = $current_user->ID;

	/*
	 * if post data exists, create the post duplicate
	 */
	if ( isset( $post ) && null !== $post ) {

		$args = array(
			'comment_status' => $post->comment_status,
			'ping_status'    => $post->ping_status,
			'post_author'    => $new_post_author,
			'post_content'   => $post->post_content,
			'post_excerpt'   => $post->post_excerpt,
			'post_name'      => $post->post_name,
			'post_parent'    => $post->post_parent,
			'post_password'  => $post->post_password,
			'post_status'    => 'draft',
			'post_title'     => $post->post_title,
			'post_type'      => $post->post_type,
			'to_ping'        => $post->to_ping,
			'menu_order'     => $post->menu_order,
		);

		/*
		 * insert the post by wp_insert_post() function
		 */
		$new_post_id = wp_insert_post( $args );

		/*
		 * get all current post terms ad set them to the new post draft
		 */
		$taxonomies = get_object_taxonomies( $post->post_type ); // returns array of taxonomy names for post type, ex array("category", "post_tag").
		foreach ( $taxonomies as $taxonomy ) {
			$post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
			wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
		}

		/*
		 * duplicate all post meta just in two SQL queries
		 */
		$post_meta_infos = $wpdb->get_results( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$post_id" ); // phpcs:ignore
		if ( count( $post_meta_infos ) !== 0 ) {
			$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
			foreach ( $post_meta_infos as $meta_info ) {
				$meta_key = $meta_info->meta_key;
				if ( '_wp_old_slug' === $meta_key ) {
					continue;
				}
				$meta_value      = addslashes( $meta_info->meta_value );
				$sql_query_sel[] = "SELECT $new_post_id, '$meta_key', '$meta_value'";
			}
			$sql_query .= implode( ' UNION ALL ', $sql_query_sel );
			$wpdb->query( $sql_query ); // phpcs:ignore
		}

		/*
		 * finally, redirect to the edit post screen for the new draft
		 */
		wp_safe_redirect( admin_url( 'post.php?action=edit&post=' . $new_post_id ) );
		exit;
	} else {
		wp_die( 'Post creation failed, could not find original post: ' . esc_html( $post_id ) );
	}
}
add_action( 'admin_action_rd_duplicate_post_as_draft', 'ufaqsw_rd_duplicate_post_as_draft' );


/**
 * Adds a 'Duplicate' link to the row actions for the custom post type 'ufaqsw'.
 *
 * @param array  $actions The existing row actions.
 * @param object $post    The current post object.
 * @return array Modified row actions with the 'Duplicate' link.
 */
function ufaqsw_rd_duplicate_post_link( $actions, $post ) {

	if ( current_user_can( 'edit_posts' ) && 'ufaqsw' === $post->post_type ) {
		$actions['duplicate'] = '<a href="' . wp_nonce_url( 'admin.php?action=rd_duplicate_post_as_draft&post=' . $post->ID, basename( __FILE__ ), 'duplicate_nonce' ) . '" title="' . esc_html__( 'Duplicate this item', 'ufaqsw' ) . '" rel="permalink">' . esc_html__( 'Duplicate', 'ufaqsw' ) . '</a>';
	}
	return $actions;
}

add_filter( 'post_row_actions', 'ufaqsw_rd_duplicate_post_link', 10, 2 );

/**
 * Custom render callback for CMB2 text_html field type.
 *
 * This function renders a text input field for the 'text_html' field type in CMB2.
 *
 * @param array  $field            The field array.
 * @param mixed  $escaped_value    The escaped value of the field.
 * @param int    $object_id        The ID of the object being edited.
 * @param string $object_type      The type of object being edited (e.g., post, user, term).
 * @param object $field_type_object The CMB2_Field object type.
 */
function bt_cmb2_render_callback_for_text_html( $field, $escaped_value, $object_id, $object_type, $field_type_object ) {
	echo $field_type_object->input( array( 'type' => 'text' ) ); // phpcs:ignore
}
add_action( 'cmb2_render_text_html', 'bt_cmb2_render_callback_for_text_html', 10, 5 );

/**
 * Sanitization callback for the 'text_html' field type in CMB2.
 *
 * This function returns the value as-is without any sanitization.
 *
 * @param mixed $override_value The override value, if any.
 * @param mixed $value          The value to sanitize.
 * @return mixed The sanitized value.
 */
function bt_cmb2_sanitize_text_html_callback( $override_value, $value ) {
	return $value;
}
add_filter( 'cmb2_sanitize_text_html', 'bt_cmb2_sanitize_text_html_callback', 10, 2 );
