<?php

/**
 * The file that defines the core plugin class
 *
 * A class definition that includes attributes and functions used across both the
 * public-facing side of the site and the admin area.
 *
 * @link       https://flothemes.com/
 * @since      1.0.0
 *
 * @package    Flo_Flex_Builder
 * @subpackage Flo_Flex_Builder/includes
 */

/**
 * The core plugin class.
 *
 * This is used to define internationalization, admin-specific hooks, and
 * public-facing site hooks.
 *
 * Also maintains the unique identifier of this plugin as well as the current
 * version of the plugin.
 *
 * @since      1.0.0
 * @package    Flo_Flex_Builder
 * @subpackage Flo_Flex_Builder/includes
 * @author     Flothemes <alexb@flothemes.com>
 */
class Flo_Flex_Builder_Stylekits {
    /**
     * The unique identifier of this plugin.
     *
     * @since    1.0.0
     * @access   protected
     * @var      string    $plugin_name    The string used to uniquely identify this plugin.
     */
    protected $plugin_name;

    protected $plugin_options;
    public function get_options() {
        return $this->plugin_options;
    }

    /**
     * The current version of the plugin.
     *
     * @since    1.0.0
     * @access   protected
     * @var      string    $version    The current version of the plugin.
     */
    protected $version;


    /**
     * The name of the plugin used to uniquely identify it within the context of
     * WordPress and to define internationalization functionality.
     *
     * @since     1.0.0
     * @return    string    The name of the plugin.
     */
    public function get_plugin_name() {
        return $this->plugin_name;
    }

    /**
     * Retrieve the version number of the plugin.
     *
     * @since     1.0.0
     * @return    string    The version number of the plugin.
     */
    public function get_version() {
        return $this->version;
    }


    /**
     * Define the core functionality of the plugin.
     *
     * Set the plugin name and the plugin version that can be used throughout the plugin.
     * Load the dependencies, define the locale, and set the hooks for the admin area and
     * the public-facing side of the site.
     *
     * @since    1.0.0
     */
    public function __construct() {
        if (defined('Flo_Flex_Builder_Version')) {
            $this->version = Flo_Flex_Builder_Version;
        } else {
            $this->version = '0.1';
        }
        $this->plugin_name = 'flo-flex-builder';

        $this->define_admin_hooks();
        $this->flo_register_menu();

        $this->plugin_options = array(
            'flex_active_stylekit_name',
            'flex_custom_stylekits_manifests',
            'flex_all_stylekits_obj',
            'flex_active_stylekits_names',
            'flex_user_data',
            'userInfo',
            'flex_stylekits_manifest',
            'flex_stylekits_pages',
            'flex_gfonts_manifest',
            'flex_typekit_manifest',
            'stylekit_permissions',
            // 'flex_subscription_order_key'
        );
    }

    /**
     * Remove get_font_styles_data filter if FLEX_THEME is defined
     */
    public function remove_filter_get_font_styles_data() {
        $flex_theme = defined('FLEX_THEME') ? FLEX_THEME : false;
        if ($flex_theme) {
            remove_filter('get_font_styles_data', 'get_font_styles_data', 10);
        }
    }

    /**
     * Add FLEX_STYLEKITS constant if option flex_active_stylekit_name exists
     */
    public function add_flex_stylekits_constant() {
        $active_name = get_option('flex_active_stylekit_name');
        if (!empty($active_name)) {
            define('FLEX_STYLEKITS', true);
        }
    }
    /**
     * Register dashboard menu related to the admin area functionality
     * of the plugin.
     *
     * @since    2.3.7
     * @access   private
     */
    private function flo_register_menu() {
        add_action('admin_menu', array(&$this, 'flo_add_flex_options'));
    }

    public function flo_add_flex_options() {
        add_menu_page('Flex Admin Settings', 'Flex Admin', 'administrator', 'flex-block-settings', array(&$this, 'flo_flex_options'), 'none');
        add_action('admin_init', 'flo_register_flex_settings');
        add_action('admin_init', array(&$this, 'flo_add_flex_options_fields'));

        function flo_register_flex_settings() {
            register_setting('flo_flex_settings', 'flo_flex_accounts');
        }
    }

    public function flo_add_flex_options_fields() {
        foreach ($this->get_options() as &$value) {
            add_option($value, '');
            register_setting('flexblock_options_group', $value);
        }
    }

    /**
     * Add the plugins settings page options
     *
     * @since    2.3.7
     */
    public function flo_flex_options() {
        include_once(dirname(dirname(__FILE__)) . '/admin/partials/flo-flex-builder-admin-display.php');
    }

    private function define_admin_hooks() {
        add_action('wp_ajax_install_stylekit', array(&$this, 'install_stylekit'));
        add_action('wp_ajax_transform_old_data', array(&$this, 'transform_old_data'));
        add_action('wp_ajax_reset_data', array(&$this, 'reset_data'));
        add_action('wp_ajax_delete_font_file', array(&$this, 'delete_font_file'));
        add_action('wp_ajax_update_any_option', array(&$this, 'update_any_option'));
        add_action('wp_ajax_regenerate_stylekit_css', array(&$this, 'regenerate_stylekit_css'));
        add_action('wp_ajax_get_installed_stylekits', array(&$this, 'get_installed_stylekits'));
        add_action('wp_ajax_upload_fonts', array(&$this, 'upload_fonts'));
        add_action('wp_ajax_get_rendered_content', function () {
            $attributes =  json_decode(stripslashes($_POST['attr']), true);
            $attributes['data'] = $attributes;
            $block_obj = new Flo_Flex_Builder_Render_Block($attributes, true);
            $block_obj->render();
            echo json_encode([
                'render' => $block_obj ? $block_obj->render() : ''
            ]);
            die();
        });
    }

    public function upload_fonts() {
        Flo_Flex_Builder_Admin::check_capabilities('administrator');

        if (isset($_FILES['files'])) {
            $uploads = wp_upload_dir();
            $uploads_dir = $uploads['basedir'];
            $uploads_url = $uploads['baseurl'];

            if (!file_exists("$uploads_dir/flex/fonts/")) {
                mkdir("$uploads_dir/flex/fonts", 0777, true);
            }
            $errors = [];
            $path = "$uploads_dir/flex/fonts/";
            $extensions = ['woff', 'woff2', 'eot', 'otf', 'ttf'];
            $all_files = count($_FILES['files']['tmp_name']);
            $response = [];
            for ($i = 0; $i < $all_files; $i++) {
                $file_name = $_FILES['files']['name'][$i];
                $file_tmp = $_FILES['files']['tmp_name'][$i];
                $file_type = $_FILES['files']['type'][$i];
                $file_size = $_FILES['files']['size'][$i];
                $file_ext = strtolower(end(explode('.', $_FILES['files']['name'][$i])));

                $file = $path . $file_name;

                if (!in_array($file_ext, $extensions)) {
                    $errors[] = 'Extension not allowed: ' . $file_name . ' ' . $file_type;
                }

                if ($file_size > 2097152) {
                    $errors[] = 'File size exceeds limit: ' . $file_name . ' ' . $file_type;
                }

                if (empty($errors)) {
                    move_uploaded_file($file_tmp, $file);
                }

                $id = strtolower(str_replace(".$file_ext", '', $file_name));
                $response[$id] = [
                    'name' => $file_name,
                    'id' =>  $id,
                    'format' => $file_ext,
                    'path' =>  $uploads_url . '/flex/fonts/' . $file_name,
                ];
            }

            echo json_encode($response);

            if ($errors) print_r($errors);
        }

        die();
    }

    public function regenerate_stylekit_css() {

        Flo_Flex_Builder_Admin::check_capabilities('administrator');

        $stylekit_id = $_POST['stylekitId'];

        delete_transient("inline_stylekit_css_{$stylekit_id}");

        //generate css font
        Flo_Flex_Builder_Typography::generateCSSFile($stylekit_id);

        $result = array(
            'response' => 'Stylekit Regenerated'
        );

        echo json_encode($result);

        die();
    }

    public function update_any_option() {

        Flo_Flex_Builder_Admin::check_capabilities('administrator');

        $options_value = json_decode(html_entity_decode(stripslashes($_POST['optionsValue'])), true);

        foreach ($options_value as $key => $value) {
            update_option($key, $value);

            // Update "blocks" entry on manifest update
            if ($key === 'flex_stylekits_manifest') {
                $stk_objs = get_option('flex_all_stylekits_obj', array());
                if (is_array($stk_objs)) {
                    $object_updated = false;
                    foreach ($stk_objs as $slug => $stk_obj) {
                        if (isset($value[$slug]['blocks']) && is_array($value[$slug]['blocks'])) {
                            $stk_objs[$slug]['blocks'] = $value[$slug]['blocks'];
                            $object_updated = true;
                        }
                    }
                    if ($object_updated) update_option('flex_all_stylekits_obj', $stk_objs);
                }
            }
        }

        $result = array(
            'response' => 'Option Updated',
        );

        echo json_encode($result);

        die();
    }

    public function enqueue_scripts($hook_suffix) {
        $script_version = $this->version;

        // if (defined('FLO_ENVIROMENT') && FLO_ENVIROMENT == 'DEV') {
        //     $script_version = mt_rand(0, 99999);
        // }

        // if ($hook_suffix == 'toplevel_page_flex-block-settings') {
        // wp_enqueue_script( $this->plugin_name . '-vendors-app', plugin_dir_url( dirname(__FILE__) ) . 'dist/flex-vendors-app.js', array( 'jquery' ), $script_version, false );
        wp_enqueue_script($this->plugin_name . '-app', plugin_dir_url(dirname(__FILE__)) . 'dist/flex-app.min.js', array('jquery', $this->plugin_name), $script_version, false);

        settings_fields('flexblock_options_group');

        $userData = [
            'site_url' => site_url(),
            'flo_environment' => defined('FLO_ENVIROMENT') ? FLO_ENVIROMENT : 'PROD',
            'flo_local_api_server' => FLEX_LOCAL_API,
            'flex_theme' => defined('FLEX_THEME') ? FLEX_THEME : false,
            'theme_fonts' => flex_get_field('flo-lyra-typography', 'options'),
            'order_key' => get_option('flotheme_theme_key'),
            'theme_name' => strtolower(str_replace(' Child', '', wp_get_theme()->Name)),
            'is_flo_theme' => flex_is_flo_theme()
        ];

        foreach ($this->get_options() as &$value) {
            $userData[$value] = get_option($value);
        }

        wp_localize_script($this->plugin_name . '-app', 'app_stylekits_data', $userData);
        // }
    }

    public function update_stylekit($stylekitToInstall) {
        //vars
        $theme_name = $stylekitToInstall['name'];
        $theme_id = $stylekitToInstall['id'];
        $stylekit_filekey = $stylekitToInstall['fileKey'];
        $amazon_url = html_entity_decode(stripslashes($_POST['amazonBase']));
        $custom_fonts = isset($stylekitToInstall['customFonts']) ? $stylekitToInstall['customFonts'] : [];
        $gfontsUrl = isset($stylekitToInstall['gFontsUrl']) ? $stylekitToInstall['gFontsUrl'] : "";
        //uploads vars
        $uploads = wp_upload_dir();
        $uploads_dir = $uploads['basedir'];
        $uploads_url = $uploads['baseurl'];

        //get stylekit
        $response = wp_remote_get($amazon_url . $stylekit_filekey);

        if (is_wp_error($response)) {
            echo $response->get_error_message();
        }

        $stylekit = json_decode($response['body'], true);
        //check if uploads exists
        if (!file_exists("$uploads_dir/flex/fonts/")) {
            mkdir("$uploads_dir/flex/fonts", 0777, true);
        }

        //get and apply customfonts
        $custom_new_fonts = [];
        foreach ($custom_fonts as $custom_font) {

            //vars
            $files = [];
            $font_id = $custom_font['id'];
            $font_name = str_replace(' ', '_', $custom_font['name']);

            foreach ($custom_font['files'] as $file) {

                //vars
                $file_format = $file['type'];
                $file_key = $file['fileKey'];


                //make url for downloaded file
                $url = "$uploads_url/flex/fonts/$font_name.$file_format";

                //save file to fonts folder if are not match with fonts names
                file_put_contents("$uploads_dir/flex/fonts/$font_name.$file_format", fopen($amazon_url . $file_key, 'r'));

                array_push($files, [
                    'url' => $url,
                    'name' => $custom_font['name'],
                    'format' => $file['type']
                ]);
            }
            //push all to array
            $custom_new_fonts["$font_id"] = [
                'name' => $custom_font['name'],
                'id' => $font_id,
                'files' => $files
            ];
        }

        $updatedStylekit = [
            'fonts' => $stylekit['fonts'],
            'colors' => $stylekit['colors'],
            "generalInfo" => [
                'name' => $theme_name,
                'id' => $theme_id,
                'customFonts' => $custom_new_fonts,
                'gFontsUrl' => $gfontsUrl
            ]
        ];

        if (isset($stylekitToInstall['blocks'])) {
            $updatedStylekit['blocks'] = $stylekitToInstall['blocks'];
        }

        return $updatedStylekit;
    }

    public function reset_data() {
        Flo_Flex_Builder_Admin::check_capabilities('administrator', $check_nonce = true);

        echo json_encode('reset');

        foreach ($this->get_options() as &$value) {
            update_option($value, '');
        }

        die();
    }

    public function delete_font_file() {
        Flo_Flex_Builder_Admin::check_capabilities('administrator', $check_nonce = true);

        $font_data = json_decode(html_entity_decode(stripslashes($_POST['fontData'])), true);
        $font_name = $font_data['files'][0]['name'] . '.' . $font_data['files'][0]['format'];


        $uploads = wp_upload_dir();
        $uploads_dir = $uploads['basedir'];
        $font_path = "$uploads_dir/flex/fonts/$font_name";

        if (file_exists($font_path)) {
            unlink($font_path);
        }

        $result = array(
            'response' => 'Font removed'
        );

        echo json_encode($result);

        die();
    }

    public function transform_old_data() {
        Flo_Flex_Builder_Admin::check_capabilities('administrator');

        $font_data = flex_get_field('flo-lyra-typography', 'options');
        if (isset($font_data['font_styles'])) {
            $sk_name = flex_get_theme() . " (custom)";

            $transform_data = Flo_Flex_Builder_Update::transform_old_data($sk_name, $font_data);
            $sk_id = $transform_data['td_custom_manifests'][0]['generalInfo']['id'];

            $options_keys = [
                // "flex_active_stylekits_names" => "td_active_stylekits_names",
                "flex_custom_stylekits_manifests" => "td_custom_manifests",
                "flex_all_stylekits_obj" => "td_all_stylekits_obj"
            ];

            foreach ($options_keys as $option_key => $transform_key) {
                $existing_value = get_option($option_key);
                if (!is_array($existing_value)) $existing_value = [];
                $new_value = array_merge($existing_value, $transform_data[$transform_key]);
                update_option($option_key, $new_value);
            }

            $flex_active_stylekits_names = get_option("flex_active_stylekits_names");
            if (empty($flex_active_stylekits_names)) $flex_active_stylekits_names = [];
            $td_name = $transform_data["td_active_stylekits_names"];
            $flex_active_stylekits_names[$sk_id] = $td_name;
            update_option("flex_active_stylekits_names", $flex_active_stylekits_names);

            Flo_Flex_Builder_Typography::generateCSSFile($sk_id);
            echo json_encode(["success" => true]);
            die();
            return;
        }

        echo json_encode(["success" => false]);

        die();
    }

    public function get_installed_stylekits() {
        Flo_Flex_Builder_Admin::check_capabilities('publish_pages');
        $all_stylekits = get_option('flex_all_stylekits_obj');
        echo json_encode($all_stylekits);
        die();
    }

    public function install_stylekit() {
        Flo_Flex_Builder_Admin::check_capabilities('administrator');

        //vars
        $stylekitData = json_decode(html_entity_decode(stripslashes($_POST['stylekit'])), true);
        $theme_id = $stylekitData['id'];
        $all_installed_stylekits = get_option('flex_all_stylekits_obj') ? get_option('flex_all_stylekits_obj') : [];
        $active_name = get_option('flex_active_stylekit_name');

        //update stylekit
        $newStylekit = $this->update_stylekit($stylekitData);

        //final array
        $all_installed_stylekits[$theme_id] = $newStylekit;

        //get active stylekits names and ids
        $flex_active_stylekits_names = flo_get_option_buffer('flex_active_stylekits_names') ? flo_get_option_buffer('flex_active_stylekits_names') : [];

        foreach ($all_installed_stylekits as $all_installed_stylekit) {
            $id =  $all_installed_stylekit['generalInfo']['id'];
            $name =  $all_installed_stylekit['generalInfo']['name'];

            $flex_active_stylekits_names[$id] = [
                'id' => $id,
                'name' => $name
            ];
        }
        //echo installed stylekits
        echo json_encode([
            'flex_all_stylekits_obj' => $all_installed_stylekits,
            'flex_active_stylekits_names' => $flex_active_stylekits_names
        ]);

        //update json
        update_option('flex_active_stylekits_names', $flex_active_stylekits_names);
        update_option('flex_all_stylekits_obj', $all_installed_stylekits);

        //generate css file for added stylekit
        if (isset($newStylekit['generalInfo']['id'])) {
            $stylekit_id = $newStylekit['generalInfo']['id'];
            Flo_Flex_Builder_Typography::generateCSSFile($stylekit_id);
        }
        die();
    }

    public function set_acf_globals() {

        global $stylekit_fonts;
        global $stylekit_colors;

        $post_id = get_the_ID();
        $stylekits_pages = get_option('flex_stylekits_pages');
        $stylekit_id_global = get_option('flex_active_stylekit_name');

        //get stylekit id by post id
        if (isset($stylekits_pages[$post_id])) {
            $stylekit_id = $stylekits_pages[$post_id]['stylekit_value'];
        } else {
            $stylekit_id = $stylekit_id_global;
        }

        $stylekits_id_obj = isset(get_option('flex_all_stylekits_obj')[$stylekit_id]) ? get_option('flex_all_stylekits_obj')[$stylekit_id] : [];
        if (!$stylekit_fonts && isset($stylekits_id_obj['fonts'])) {
            $stylekit_fonts = $stylekits_id_obj['fonts'];
        }

        if (!$stylekit_colors && isset($stylekits_id_obj['colors'])) {
            $stylekit_colors = $stylekits_id_obj['colors'];
        }
    }

    public function remove_flex_admin_non_flex() {
        $style_parent_theme = wp_get_theme(get_template());
        $author = $style_parent_theme->get('Author');

        if (!defined('FLEX_THEME') && $author === 'Flothemes') {
            remove_menu_page('flex-block-settings');
        }
    }

    //static method that update flex_stylekits_pages option
    public static function update_stylekit_pages($array) {
        $stylekit_pages = get_option('flex_stylekits_pages') ? get_option('flex_stylekits_pages') : [];

        foreach ($array as $key => $value) {
            $checkbox = $value['enabled'];
            if ($checkbox && !empty($value['stylekit_value'])) {
                $stylekit_pages[$key] = $value;
            } else {
                if (isset($stylekit_pages[$key])) {
                    unset($stylekit_pages[$key]);
                }
            }
        }

        update_option('flex_stylekits_pages', $stylekit_pages);
    }
}
