<?php
/**
 * Plugin Service Provider File
 *
 * @category   Core
 * @package    CodexShaper_Framework
 * @author     CodexShaper <info@codexshaper.com>
 * @license    https://www.gnu.org/licenses/gpl-2.0.html
 * @link       https://codexshaper.com
 * @since      1.0.0
 */

namespace CodexShaper\Framework\Providers;

use CodexShaper\Framework\Admin\Menu;
use CodexShaper\Framework\Foundation\DynamicMetabox;
use CodexShaper\Framework\Foundation\DynamicPostType;
use CodexShaper\Framework\Foundation\DynamicTaxonomy;
use CodexShaper\Framework\Foundation\ServiceProvider;
use CodexShaper\Framework\Foundation\Traits\Hook;

// Exit if access directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit();
}

/**
 * Plugin Service Provider Class
 *
 * @category   Class
 * @package    CodexShaper_Framework
 * @author     CodexShaper <info@codexshaper.com>
 * @license    https://www.gnu.org/licenses/gpl-2.0.html
 * @link       https://codexshaper.com
 * @since      1.0.0
 */
class PluginServiceProvider extends ServiceProvider {

	use Hook;

	/**
	 * Widget Manager
	 *
	 * @since 1.0.0
	 * @var CodexShaper\Framework\Managers\WidgetManager  Widget manager.
	 */
	protected $widget_manager;

	/**
	 * The plugin options.
	 *
	 * @var array $options Plugin options.
	 */
	protected $options = array();

	/**
	 * The provider class names.
	 *
	 * @var string[]
	 */
	public $providers = array(
		AssetsServiceProvider::class,
		AdminServiceProvider::class,
		'plugins_loaded' => array(
			ElementorServiceProvider::class,
		),
	);

	/**
	 * The singletons to register into the container.
	 *
	 * @var array
	 */
	public $singletons = array();

	/**
	 * Constructor
	 *
	 * Admin menu register.
	 *
	 * @since 1.0.0
	 * @access public
	 */
	public function register() {

		$this->options   = csmf_config( 'options' );
		$this->providers = apply_filters( 'csmf_plugin_providers', $this->providers );

		$this->app->callMethod( array( $this, 'includes' ) );

		// Includes files.
		// $this->includes();
		// Initialize admin menu.
		Menu::instance();

		// Add custom icon.
		$this->add_filter( 'csmf_field_icon_add_icons', 'csmf_custom_icon' );
		// $this->add_filter('admin_init', 'import_demo_data', 9);
		// $this->add_filter('admin_init', 'setup_default_settings', 11);

		// Register dynamic custom posts.
		$this->app->callMethod( array( $this, 'create_dynamic_post_types' ) );
		// Register dynamic custom taxonomies.
		$this->app->callMethod( array( $this, 'create_dynamic_taxonomies' ) );
		$this->app->callMethod( array( $this, 'create_dynamic_metaboxes' ) );

		$this->add_action( 'plugins_loaded', 'csmf_plugins_loaded', 100 );

		add_filter( 'admin_init', array( $this, 'add_cache_options' ) );
	}

	/**
	 * Add Cache Option.
	 * 
	 * @access public
	 * @return void
	 */
	public function add_cache_options() {
		$post_types = csmf_get_post_types();
		$taxonomies = csmf_get_taxonomies();
		update_option( 'csmf_post_types_cache', $post_types );
		update_option( 'csmf_taxonomies_cache', $taxonomies );
	}

	/**
	 * Plugin loaded
	 *
	 * @since 1.0.0
	 * @access public
	 * @static
	 * @return void
	 */
	public function csmf_plugins_loaded() {
		// Element bucket initialize.

		$files = array(
			array(
				'name' => 'custom-post-types',
				'path' => 'inc/options',
			),
			array(
				'name' => 'taxonomies',
				'path' => 'inc/options',
			),
		);

		foreach ( $files as $file ) {

			$file_path = CSMF_PATH . $file['path'] . '/' . $file['name'] . '.php';

			if ( file_exists( $file_path ) ) {
				require_once $file_path;
			}
		}
	}

	/**
	 * Register widgets
	 *
	 * @since 1.0.0
	 * @access public
	 * @static
	 * @return void
	 */
	public function register_widgets() {
		// Initialize WordPress widgets.
	}

	/**
	 * Includes
	 *
	 * Load all required static files.
	 *
	 * @since 1.0.0
	 * @access private
	 *
	 * @return void
	 */
	public function includes() {

		$files = array(
			array(
				'name' => 'autoload',
				'path' => '',
			),
			array(
				'name' => 'codestar-framework',
				'path' => 'lib/codestar-framework',
			),
			array(
				'name' => 'general',
				'path' => 'inc/helpers',
			),
			array(
				'name' => 'core',
				'path' => 'inc/helpers',
			),
			array(
				'name' => 'inflector',
				'path' => 'inc/utils',
			),
		);

		foreach ( $files as $file ) {

			$file_path = CSMF_PATH . $file['path'] . '/' . $file['name'] . '.php';

			if ( file_exists( $file_path ) ) {
				require_once $file_path;
			}
		}
	}

	/**
	 * Create dynamic custom post types
	 *
	 * @since 1.0.0
	 * @access public
	 * @return void
	 */
	public function create_dynamic_post_types() {
		$custom_post_type_option_name = csmf_config( 'options.cpt.option_name' );
		$cpt_options                  = csmf_settings( $custom_post_type_option_name );
		$options                      = $cpt_options['csmf_cpt_options'] ?? array();

		if ( ! is_array( $options ) || empty( $options ) ) {
			return;
		}

		foreach ( $options as $option ) {

			$post_type     = $option['post_type'] ?? '';
			$singular_name = $option['singular_name'] ?? '';
			$plural_name   = $option['plural_name'] ?? '';
			$menu_name     = $option['menu_name'] ?? '';
			$is_active     = $option['is_active'] ?? false;

			if ( ! $is_active || ! $post_type || ! $singular_name || ! $plural_name ) {
				continue;
			}

			$supports = $option['supports'] ?? array( 'title' );

			if ( empty( $supports ) ) {
				$supports = array( 'title' );
			}

			new DynamicPostType(
				array(
					'post_type'           => $post_type,
					'name'                => $plural_name,
					'singular_name'       => $singular_name,
					'plural_name'         => $plural_name,
					'menu_name'           => $menu_name,
					'supports'            => $supports,
					'rewrite'             => isset( $option['slug'] ) && $option['slug'] != '' ? array(
						'slug'       => $option['slug'],
						'with_front' => false,
					) : array(),
					'exclude_from_search' => isset( $option['exclude_from_search'] ) && $option['exclude_from_search'] === '1' ? true : false,
					'has_archive'         => isset( $option['has_archive'] ) && $option['has_archive'] === '1' ? true : false,
					'publicly_queryable'  => isset( $option['publicly_queryable'] ) && $option['publicly_queryable'] === '1' ? true : false,
					'hierarchical'        => false,
					'show_in_menu'        => isset( $option['show_in_menu'] ) && $option['show_in_menu'] === '1' ? true : false,
					'show_ui'             => isset( $option['show_ui'] ) && $option['show_ui'] === '1' ? true : false,
					'show_in_nav_menus'   => isset( $option['show_in_nav_menus'] ) && $option['show_in_nav_menus'] === '1' ? true : false,
					'menu_icon'           => isset( $option['icon']['url'] ) && $option['icon']['url'] != '' ? $option['icon']['url'] : false,
					'is_active'           => $is_active,
				)
			);
		}
	}

	/**
	 * Create dynamic custom taxonomies
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function create_dynamic_taxonomies() {

		$custom_taxonomy_option_name = csmf_config( 'options.taxonomy.option_name' );
		$taxonomy_options            = csmf_settings( $custom_taxonomy_option_name );
		$options                     = $taxonomy_options['csmf_taxonomy_options'] ?? array();

		if ( ! is_array( $options ) || empty( $options ) ) {
			return;
		}

		foreach ( $options as $option ) {

			$taxonomy  = $option['taxonomy'] ?? '';
			$is_active = isset( $option['is_active'] ) && $option['is_active'] === '1';

			if ( ! $is_active || ! $taxonomy ) {
				continue;
			}

			$plural_label   = $option['taxonomy_plural_label'];
			$singular_label = $option['taxonomy_label'];
			$name = $plural_label;
			$singular_name = $singular_label;

			$search_items = sprintf(
				// Translators: %s: Taxonomy general name.
				__( 'Search %s', 'codexshaper-framework' ),
				$plural_label
			);

			$all_items = sprintf(
				// Translators: %s: Taxonomy general name.
				__( 'All %s', 'codexshaper-framework' ),
				$plural_label
			);

			$parent_item = sprintf(
				// Translators: %s: Taxonomy singular name.
				__( 'Parent %s', 'codexshaper-framework' ),
				$singular_label
			);

			$parent_item_colon = sprintf(
				// Translators: %s: Taxonomy singular name.
				__( 'Parent %s :', 'codexshaper-framework' ),
				$singular_label
			);

			$edit_item = sprintf(
				// Translators: %s: Taxonomy singular name.
				__( 'Edit %s', 'codexshaper-framework' ),
				$singular_label
			);

			$update_item = sprintf(
				// Translators: %s: Taxonomy singular name.
				__( 'Update %s', 'codexshaper-framework' ),
				$singular_label
			);

			$add_new_item = sprintf(
				// Translators: %s: Taxonomy singular name.
				__( 'Add New %s', 'codexshaper-framework' ),
				$singular_label
			);

			$new_item_name = sprintf(
				// Translators: %s: Taxonomy singular name.
				__( 'New %s Name', 'codexshaper-framework' ),
				$singular_label
			);

			new DynamicTaxonomy(
				array(
					'taxonomy'           => $taxonomy, // Required.
					'name'               => $name,
					'singular_name'      => $singular_name,
					'search_items'       => $search_items,
					'all_items'          => $all_items,
					'parent_item'        => $parent_item,
					'parent_item_colon'  => $parent_item_colon,
					'edit_item'          => $edit_item,
					'update_item'        => $update_item,
					'add_new_item'       => $add_new_item,
					'new_item_name'      => $new_item_name,
					'menu_name'          => $plural_label,
					'object_type'        => isset( $option['object_type'] ) && is_array( $option['object_type'] ) ? $option['object_type'] : array(),
					'hierarchical'       => true,
					'show_ui'            => isset( $option['show_ui'] ) && $option['show_ui'] === '1' ? true : false,
					'show_admin_column'  => true,
					'query_var'          => true,
					'rewrite'            => isset( $option['slug'] ) && $option['slug'] != '' ? array(
						'slug'       => $option['slug'],
						'with_front' => false,
					) : false,
					'public'             => isset( $option['public'] ) && $option['public'] === '1' ? true : false,
					'publicly_queryable' => isset( $option['publicly_queryable'] ) && $option['publicly_queryable'] === '1' ? true : false,
					'show_in_menu'       => isset( $option['show_in_menu'] ) && $option['show_in_menu'] === '1' ? true : false,
					'show_in_nav_menus'  => isset( $option['show_in_nav_menus'] ) && $option['show_in_nav_menus'] === '1' ? true : false,
					'show_in_rest'       => isset( $option['show_in_rest'] ) && $option['show_in_rest'] === '1' ? true : false,
					'is_active'          => $is_active,
				)
			);
		}
	}

	/**
	 * Create dynamic custom taxonomies
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @return void
	 */
	public function create_dynamic_metaboxes() {

		$option_settings     = csmf_config( 'options' ) ?? array();
		$metabox_config      = $option_settings['metabox'] ?? array();
		$section_config      = $option_settings['section'] ?? array();
		$field_config        = $option_settings['field'] ?? array();
		$metabox_prefix      = $metabox_config['prefix'] ?? 'csmf_metabox_settings';
		$metabox_option_name = $metabox_config['option_name'] ?? 'csmf_metabox_options';
		$section_prefix      = $section_config['prefix'] ?? 'csmf_metabox_settings';
		$section_option_name = $section_config['option_name'] ?? 'csmf_metabox_section_settings';
		$field_prefix        = $field_config['prefix'] ?? 'csmf_metabox_settings';
		$field_option_name   = $field_config['option_name'] ?? 'csmf_metabox_section_field_settings';
		$metabox_options     = csmf_settings( $metabox_prefix );
		$section_options     = csmf_settings( $section_prefix );
		$field_options       = csmf_settings( $field_prefix );

		$metaboxes = $metabox_options[ $metabox_option_name ] ?? array();
		$sections  = $section_options[ $section_option_name ] ?? array();
		$fields    = $field_options[ $field_option_name ] ?? array();

		if ( ! is_array( $metaboxes ) || empty( $metaboxes ) ) {
			return;
		}

		if ( ! is_array( $sections ) ) {
			$sections = (array) $sections;
		}

		if ( ! is_array( $fields ) ) {
			$fields = (array) $fields;
		}

		foreach ( $metaboxes as $option ) {

			$is_active = $option['is_active'] ?? false;

			if ( ! $is_active ) {
				continue;
			}

			$metabox_sections = array_reduce(
				$sections,
				function ( $carry, $section ) use ( $option ) {
					$is_active = $section['is_active'] ?? true;
					if ( $is_active && isset( $section['metabox_id'] ) ) {
						foreach ( $section['metabox_id'] as $metabox_id ) {
							if ( $metabox_id !== $option['id'] ) {
								continue;
							}

							$parent = $section['parent'] ?? '';

							$carry[] = array(
								'id'     => $section['id'],
								'title'  => $section['title'],
								'parent' => $parent != $section['id'] ? $parent : '',
							);
						}
					}

					return $carry;
				},
				array()
			);

			foreach ( $metabox_sections as &$section ) {

				$section['fields'] = array_reduce(
					$fields,
					function ( $carry, $field ) use ( $section ) {
						$is_active = $field['is_active'] ?? true;
						if ( $is_active && isset( $field['section_id'] ) ) {
							foreach ( $field['section_id'] as $section_id ) {
								if ( $section_id === $section['id'] ) {
									$carry[] = array(
										'id'          => $field['id'],
										'type'        => $field['type'] ?? 'text',
										'title'       => $field['title'] ?? 'Test Title',
										'options'     => isset( $field['options'] ) ? json_decode( $field['options'], true ) : '',
										'default'     => $field['default'] ?? '',
										'subtitle'    => $field['subtitle'] ?? '',
										'description' => $field['description'] ?? '',
										'class'       => $field['class'] ?? '',
										'dependency'  => $field['dependency'] ?? '',
										'attributes'  => isset( $field['attributes'] ) ? json_decode( $field['attributes'], true ) : '',
									);
								}
							}
						}

						return $carry;
					},
					array()
				);
			}

			unset( $section );

			$args = array(
				'screen'        => $option['screen'] ?? array(),
				'title'         => $option['title'] ?? '',
				'plural_title'  => $option['plural_title'] ?? '',
				'context'       => $option['context'] ?? 'advanced',
				'priority'      => $option['priority'] ?? 'default',
				'callback_args' => $option['callback_args'] ?? null,
				'is_serialize'  => $option['is_serialize'] ?? true,
				'is_active'     => $option['is_active'] ?? true,
			);

			new DynamicMetabox( $option['id'], $metabox_sections, $args );
		}
	}

	/**
	 * Import Demo data
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function import_demo_data() {
		// $importer = new Importer();

		// $importer->import_demo_content();
		// $importer->setup_theme_options( '', 'csmf_theme_options' );
		// $importer->import_widgets();
		// $importer->import_customizer();
	}

	public function setup_default_settings() {
		// $main_menu   = get_term_by( 'name', 'Main Menu', 'nav_menu' );
		// $footer_menu = get_term_by( 'name', 'Footer Quick Links', 'nav_menu' );

		// set_theme_mod(
		// 'nav_menu_locations',
		// array(
		// 'main-menu'   => $main_menu->term_id,
		// 'footer-menu' => $footer_menu->term_id,
		// )
		// );

		// // Assign front page and posts page (blog page).
		// $front_page_id = csmf_get_page_by_title( 'Home One' );
		// $blog_page_id  = csmf_get_page_by_title( 'Blog' );

		// update_option( 'show_on_front', 'page' );
		// update_option( 'page_on_front', $front_page_id->ID );
		// update_option( 'page_for_posts', $blog_page_id->ID );
	}

	/**
	 * Custom icon
	 *
	 * Load custom icon
	 *
	 * @param array $icons Custom icons.
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	public function csmf_custom_icon( $icons ) {
		// Adding new icon.
		$icons[] = array(
			'title' => esc_html__( 'Flaticon', 'codexshaper-framework' ),
			'icons' => array(
				'flaticon-right-arrow',
				'flaticon-left-arrow',
			),
		);
		$icons   = array_reverse( $icons );
		return $icons;
	}
}
