<?php

if (!defined('ABSPATH')) {
    exit;
}

if (!class_exists('ReonMetaBox')) {

    class ReonMetaBox {

        private static $post_metaboxes = array();

        public static function init() {
            add_action('add_meta_boxes', array(new self(), 'init_metaboxes'));
            add_action('save_post', array(new self(), 'save_post_metabox'), 10, 3);
        }

        public static function init_metaboxes() {

            foreach (self::get_metaboxes() as $metabox) {
                add_meta_box($metabox['id'], $metabox['title'], array(new self(), 'render_metabox'), $metabox['screen'], $metabox['context'], $metabox['priority']);
            }
        }

        public static function render_metabox($post, $args) {

            $post_id = $post->ID;
            $metabox = self::get_metabox($args['id']);
            $metabox['fields'] = ReonCore::process_default_post_metabox_fields(apply_filters('reon/get-metabox-' . $metabox['id'] . '-fields', $metabox['fields'], $metabox['id'], $post_id));
            $metabox['nonce_path'] = basename(__FILE__);

            do_action('reon/render-metabox', $metabox, $post_id);
        }

        public static function save_post_metabox($post_id, $post, $update) {

            foreach (self::get_metaboxes() as $metabox) {

                $is_autosave = wp_is_post_autosave($post_id);
                $is_revision = wp_is_post_revision($post_id);
                $is_valid_nonce = ( isset($_POST['reon_post_meta' . $metabox['id']]) && wp_verify_nonce($_POST['reon_post_meta' . $metabox['id']], basename(__FILE__)) ) ? true : false;

                if ($is_autosave || $is_revision || !$is_valid_nonce) {
                    continue;
                }
                $metabox['fields'] = ReonCore::process_default_post_metabox_fields(apply_filters('reon/get-metabox-' . $metabox['id'] . '-fields', $metabox['fields'], $metabox['id'], $post_id, $update));


                $post_metas = array();

                $valuas_id = 'reon_metabox_' . $metabox['id'] . '_value';

                if (isset($_POST[$valuas_id])) {
                    $valuas_array = json_decode(wp_unslash($_POST[$valuas_id]), true);
                    if (is_array($valuas_array) && isset($valuas_array[$metabox['id']])) {
                        $post_metas = apply_filters('reon/save_all_' . $metabox['id'] . '_post_metas', self::sanitize_meta_option($metabox['id'], $post_id, $valuas_array[$metabox['id']]), $post_id);
                    }
                }

                if ($metabox['save_metabox'] == true) {
                    $field_ids = ReonUtil::get_controls_field_ids($metabox['fields']);
                    foreach ($field_ids as $field_id) {
                        if (isset($post_metas[$field_id])) {
                            update_post_meta($post_id, $field_id, $post_metas[$field_id]);
                        } else {
                            delete_post_meta($post_id, $field_id);
                        }
                    }
                }
            }
        }

        public static function get_metabox($id = '') {
            if ($id == '') {
                return array();
            }
            foreach (self::get_metaboxes() as $metabox) {
                if ($metabox['id'] == $id) {
                    $mt = apply_filters('reon/get-metabox', $metabox);
                    return $mt;
                }
            }
            return array();
        }

        public static function get_metaboxes() {
            return self::$post_metaboxes;
        }

        public static function set_metabox($args = array()) {
            $metabox = self::default_metabox();
            foreach ($args as $key => $value) {
                $metabox[$key] = $value;
            }

            self::$post_metaboxes[] = apply_filters('reon/set-metabox', $metabox);
        }

        private static function default_metabox() {

            $args = array(
                'id' => 'reon',
                'title' => '',
                'screen' => array('page', 'post'),
                'context' => 'advanced',
                'priority' => 'default',
                'save_metabox' => true,
                'fields' => array()
            );
            return $args;
        }

        private static function sanitize_meta_option($metabox_id, $post_id, $options = array()) {


            $field_types = self::get_field_types($metabox_id, $post_id);

            $opt = array();
            foreach ($field_types as $field_type) {
                if (isset($options[$field_type['id']])) {
                    $opt[$field_type['id']] = apply_filters('reon/sanitize-' . $field_type['type'], $options[$field_type['id']], $options[$field_type['id']], $field_type['id'], $field_type['children']);
                }
            }

            return $opt;
        }

        private static function get_field_types($metabox_id, $post_id) {

            $field_args = array(
                'screen' => 'metabox',
                'metabox_id' => $metabox_id,
                'post_id' => $post_id
            );

            $field_types = array();

            $metabox = self::get_metabox($metabox_id);
            $metabox['fields'] = apply_filters('reon/get-metabox-' . $metabox['id'] . '-fields', ReonCore::process_default_post_metabox_fields($metabox['fields']), $metabox['id'], $post_id);


            foreach ($metabox['fields'] as $field) {

                if (isset($field['merge_fields']) && $field['merge_fields'] == false && isset($field['fields'])) {
                    foreach (ReonUtil::get_controls_field_types($field['fields'], $field_args) as $field_type) {
                        $field_types[] = array(
                            'id' => $field_type['id'],
                            'type' => $field_type['type'],
                            'screen' => $field_type['screen'],
                            'metabox_id' => $field_type['metabox_id'],
                            'post_id' => $field_type['post_id'],
                            'children' => $field_type['children']
                        );
                    }
                } else {
                    $field_types[] = array(
                        'id' => $field['id'],
                        'type' => $field['type'],
                        'screen' => 'metabox',
                        'metabox_id' => $metabox_id,
                        'post_id' => $post_id,
                        'children' => apply_filters('reon/get-' . $field['type'] . '-children-types', array(), $field, $field_args)
                    );
                }
            }
            return $field_types;
        }

    }

}