<?php
/**
 * Library object meta boxes handler
 *
 * @package "All In One Meta" library
 * @since   1.0.0
 * @version 1.0.0
 */

// Prevent direct script access.
if ( !defined( 'ABSPATH' ) ) {
	die( 'No direct script access allowed' );
}

if( ! class_exists( 'AIOM_Object_Metabox' ) ) {

	abstract class AIOM_Object_Metabox {

		/**
		 * Holds meta box ID
		 * @var string|null
		 */
		protected $id = NULL;

		/**
		 * Holds meta box title
		 * @var string
		 */
		protected $title = '';

		/**
		 * Get meta box title
		 * @param string $default Default title
		 *
		 * @return string
		 */
		protected function get_title( $default = '' ) {
			if( ! $this->title && $default ) {
				$this->title = sprintf( __( '%s Advanced Fields', 'aiom' ), $default );
			}

			return $this->title;
		}

		/**
		 * Holds fields configuration
		 * @var array
		 */
		protected $fields = null;

		/**
		 * Holds callback that provide fields structure
		 * @var
		 */
		protected $fields_callback;

		/**
		 * Holds fields that have columns in taxonomy terms table
		 */
		protected $fields_with_columns;

		/**
		 * AIOM_Taxonomy_Metabox constructor.
		 *
		 * @param array $args
		 * @param       $fields_callback Callback that provides fields structure
		 */
		public function __construct( $args, $fields_callback ) {
			if( $this->validate_args( $args ) ) {
				$this->setup_args( $args );
				$this->setup_fields_callback( $fields_callback );
				$this->hooks();
			}
		}

		/**
		 * Parse and validate metabox configuration
		 *
		 * @param array $args
		 * @return bool
		 */
		protected function validate_args( &$args ) {
			return true;
		}

		/**
		 * Setup metabox arguments
		 *
		 * @param array $args
		 */
		abstract protected function setup_args( $args );

		/**
		 * Setup fields callback
		 *
		 * @param string|array $callback Callback that provides fields structure
		 */
		protected function setup_fields_callback( $callback ) {
			$this->fields_callback = $callback;
		}

		/**
		 * Get fields
		 * @return array
		 */
		abstract protected function get_fields();

		/**
		 * Get fields that have columns in taxonomy terms table
		 * @return array
		 */
		protected function get_fields_with_columns() {
			if( null === $this->fields_with_columns ) {
				$fields = array();
				foreach( $this->get_fields() as $tab => $config ) {
					$fields = array_merge( $fields, array_filter( $config[ 'fields' ], function( $field ){
						return (
							isset( $field[ 'table_col' ] )
							&& isset( $field[ 'table_col' ][ 'heading' ] )
							&& isset( $field[ 'table_col' ][ 'callback' ] )
							&& is_callable( $field[ 'table_col' ][ 'callback' ] )
						);
					} ) );
				}

				if( ! empty( $fields ) ) {
					uasort( $fields, function( $a, $b ) {
						$a_order = isset( $a[ 'table_col' ][ 'order' ] ) ? absint( $a[ 'table_col' ][ 'order' ] ) : 10;
						$b_order = isset( $b[ 'table_col' ][ 'order' ] ) ? absint( $b[ 'table_col' ][ 'order' ] ) : 10;

						return $a_order - $b_order;
					} );
				}
				$this->fields_with_columns = $fields;
			}

			return $this->fields_with_columns;
		}

		/**
		 * Setup generic actions
		 */
		protected function hooks() {
			add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ), 11 );
		}

		/**
		 * Check whether current screen the required one
		 * @return bool
		 */
		abstract protected function is_appropriate_screen();

		/**
		 * Enqueue Scripts and Styles
		 */
		public function admin_enqueue_scripts() {

			if ( $this->is_appropriate_screen() ) {

				wp_enqueue_style( 'aiom-style' );
				wp_enqueue_script( 'aiom-script' );

				if ( ! class_exists( 'AIOM_Renderer' ) ) {
					require_once( 'class-aiom-renderer.php' );
				}

				$types = array();
				foreach( $this->get_fields() as $tab_id => $tab ) {
					$types = array_merge( $types, array_values( wp_list_pluck( $tab[ 'fields' ], 'type', '' ) ) );
				}
				foreach( $types as $type ) {
					if( $handler = AIOM_Renderer::get_field_handler( $type ) ) {
						call_user_func( array( $handler, 'enqueue' ) );
					}
				}
			}
		}

		/**
		 * Manage taxonomy terms list table columns
		 * @param array $columns Current columns
		 *
		 * @return array
		 */
		public function manage_list_table_columns( $columns ) {
			$fields = $this->get_fields_with_columns();
			if( ! empty( $fields ) ) {
				foreach ( $fields as $id => $field ) {
					$columns[ $id ] = $field['table_col']['heading'];
				}
			}

			return $columns;
		}

	}

}