<?php
/**
 * TODO: -- after switch theme, if option not exists flex_all_stylekits_obj, install_stylekit
 * TODO: -- after theme update, if option not exists flex_all_stylekits_obj, and exists option flo_lyra_typography, transform_old_data
 * TODO: -- after plugin update, if option not exists flex_all_stylekits_obj and if FLEX_THEME, install_stylekit
 * TODO: -- after plugin enable, if option not exists flex_all_stylekits_obj and if FLEX_THEME, install_stylekit
 */

/**
 *
 * Methods used for switch,update,enable of themes and plugins
 *
 * Main purpose of this class is to keep all methods used on
 * switch,update,enable of themes and plugins
 *
 */
/**
 * Fallback for ACF get_field option, in case it's unninstalled
 */
if ( ! function_exists('flex_get_field') ) {
	function flex_get_field($op, $source = 'options') {
			if ( function_exists('get_field') ) {
				return get_field($op, $source);
			}
			return false;
	}
}

class Flo_Flex_Builder_Update {

    static $amazonBase = "https://bucket-flexblock-assets.s3.amazonaws.com/";
    static $publicApi = "http://serviceflexblockassets-env.eba-mst3munp.us-east-1.elasticbeanstalk.com/";

    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';
    }

    public static function handle_theme_update() {
        self::handle_plugin_update();
    }

    public static function handle_plugin_update() {
        //vars
        $active_stylekit_name = get_option('flex_active_stylekit_name');
        $theme_slug = strtolower(wp_get_theme()->get('Name'));
        $theme_name = 'Custom Stylekit';
        $font_data = flex_get_field('flo-lyra-typography', 'options');
        
        if (!$active_stylekit_name) {
            if (isset($font_data['font_styles'])) {
                $transform_data = self::transform_old_data($theme_name, $font_data);
                $active_stylekit_names = $transform_data['td_active_stylekits_names'];
                $all_stylekits_obj = $transform_data['td_all_stylekits_obj'];
                $active_stylekit_name = $transform_data['td_active_name'];

                update_option('flex_custom_stylekits_manifests', $transform_data['td_custom_manifests']);
            } else {
                $installed_stylekit = self::install_stylekit($theme_slug);
                $active_stylekit_names = $installed_stylekit['is_active_stylekits_name'];
                $all_stylekits_obj = $installed_stylekit['is_all_stylekits_obj'];
                $active_stylekit_name = $installed_stylekit['is_active_name'];
            }

            update_option('flex_active_stylekit_name', $active_stylekit_name);
            update_option('flex_active_stylekits_names', $active_stylekit_names);
            update_option('flex_all_stylekits_obj', $all_stylekits_obj);

            Flo_Flex_Builder_Typography::generateCSSFile($active_stylekit_name);
        }
    }

    public static function handle_switch() {
        //vars
        $active_stylekit_name = get_option('flex_active_stylekit_name');
        $theme_slug = strtolower(wp_get_theme()->get('Name'));
        $theme_name = 'Custom Stylekit';
        $font_data = flex_get_field('flo-lyra-typography', 'options');

        if (!$active_stylekit_name) {
            if(defined('FLEX_THEME')) {
                $transform_data = [];
                if (isset($font_data['font_styles'])) {
                    //transform and install
                    $transform_data = self::transform_old_data($theme_name, $font_data);
                }

                $installed_stylekit = self::install_stylekit($theme_slug);
                //merge indexes with options thats need to update the both
                if(isset($transform_data['td_all_stylekits_obj'])) {
                    $active_stylekit_names = array_merge($transform_data['td_active_stylekits_names'], $installed_stylekit['is_active_stylekits_name']);
                    $all_stylekits_obj = array_merge($transform_data['td_all_stylekits_obj'], $installed_stylekit['is_all_stylekits_obj']);
                } else {
                    $active_stylekit_names = $installed_stylekit['is_active_stylekits_name'];
                    $all_stylekits_obj = $installed_stylekit['is_all_stylekits_obj'];
                }

                update_option('flex_active_stylekit_name', $installed_stylekit['is_active_name']);
                update_option('flex_active_stylekits_names', $active_stylekit_names);
                update_option('flex_all_stylekits_obj', $all_stylekits_obj);

                Flo_Flex_Builder_Typography::generateCSSFile($installed_stylekit['is_active_name']);
                if(isset($transform_data['td_active_name'])) {
                    update_option('flex_custom_stylekits_manifests', $transform_data['td_custom_manifests']);
                    Flo_Flex_Builder_Typography::generateCSSFile($transform_data['td_active_name']);
                }
            }
        }
    }

    public static function update_stylekit($stylekitToInstall) {
        //vars
        $amazon_url = self::$amazonBase;

        $theme_name = $stylekitToInstall['name'];
        $theme_id = $stylekitToInstall['id'];
        $stylekit_filekey = $stylekitToInstall['fileKey'];
        $custom_fonts = isset($stylekitToInstall['customFonts']) ? $stylekitToInstall['customFonts'] : [];
        $gfontsUrl = $stylekitToInstall['gFontsUrl'];
        //uploads vars
        $uploads = wp_upload_dir();
        $uploads_dir = $uploads['basedir'];
        $uploads_url = $uploads['baseurl'];

        //get stylekit
        $stylekit_url = $amazon_url . $stylekit_filekey;
                    
        $stylekit_req = wp_remote_get($stylekit_url);
        
        if(!is_wp_error($stylekit_req) && isset($stylekit_req['body'])) {
            $stylekit_json = $stylekit_req['body'];
        } else {
            $stylekit_json = file_get_contents($stylekit_url);
        }
        $stylekit = json_decode($stylekit_json, 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 = [];
        if(is_array($custom_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
                    $font_url = $amazon_url . $file_key;
                    
                    $font_req = wp_remote_get($font_url);

                    if(!is_wp_error($font_req) && isset($font_req['body'])) {
                        $font_content = $font_req['body'];
                    } else {
                        $font_file = file_get_contents($font_url);
                    }

                    file_put_contents("$uploads_dir/flex/fonts/$font_name.$file_format", $font_content);

                    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 static function install_stylekit($slug) {

        $apiUrl = self::$publicApi;
        if(defined("FLO_ENVIROMENT")) {
            if(FLO_ENVIROMENT === "DEMO") {
                $apiUrl = "http://flexapi-dev.us-east-1.elasticbeanstalk.com/";
            } else if(FLO_ENVIROMENT === "DEMO") {
                $apiUrl = "http://localhost:5000/";
            }
        }
        
        $stylekit_req = wp_remote_get("{$apiUrl}stylekits/manifest/{$slug}");

        if(!is_wp_error($stylekit_req) && isset($stylekit_req['body'])) {
            $stylekit = $stylekit_req['body'];
        } else {
            return [
                'is_active_name' => '',
                'is_active_stylekits_name' => [],
                'is_all_stylekits_obj' => []
            ];
        }

        //vars
        $stylekitData = json_decode(html_entity_decode(stripslashes($stylekit)), true);
        $theme_id = $stylekitData['id'];
        $all_installed_stylekits = get_option('flex_all_stylekits_obj');
        if(!$all_installed_stylekits) $all_installed_stylekits = [];


        //update stylekit
        $newStylekit = self::update_stylekit($stylekitData);

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

        //get active stylekits names and ids
        $flex_active_stylekits_names = get_option('flex_active_stylekits_names');
        if(!$flex_active_stylekits_names) $flex_active_stylekits_names = [];

        $flex_active_stylekits_names[$theme_id] = [
            'id' => $all_installed_stylekits[$theme_id]['generalInfo']['id'],
            'name' => $all_installed_stylekits[$theme_id]['generalInfo']['name']
        ];

        return [
            'is_active_name' => $theme_id,
            'is_active_stylekits_name' => $flex_active_stylekits_names,
            'is_all_stylekits_obj' => $all_installed_stylekits
        ];
    }

    public static function generateFontStyle($font_id, $font_style) {
        $cleanFontFamily = str_replace('"', '', explode(',', $font_style['font_family'])[0]);
        return [
            "id" => $font_id,
            "label" => $font_style["font_style_name"],
            "lineHeight" => $font_style["line_height"],
            "fontSize" => $font_style["font_size"],
            "letterSpacing" => $font_style["letter_spacing"],
            "fontFamily" => $cleanFontFamily,
            "fontWeight" => "normal",
            "fontStyle" => "normal",
            "textDecoration" => "none",
            "textTransform" => $font_style["default"]["font_case"],
            "mobile" => [
                "fontSize" => isset($font_style["font_size_mobile"]) ? $font_style["font_size_mobile"] : null,
                "lineHeight" => isset($font_style["line_height_mobile"]) ? $font_style["line_height_mobile"] : null,
                "letterSpacing" => isset($font_style["letter_spacing_mobile"]) ? $font_style["letter_spacing_mobile"] : null,
            ]
        ];
    }

    public static function parseFontStyles($font_styles, $are_custom = false) {

        $parsed_font_styles = [];
        $stylekit_fonts = [];
        $custom_fonts = [];
        $google_font_names = [];
        $typekit_fonts = [];

        //uploads vars
        $uploads = wp_upload_dir();
        $uploads_dir = $uploads['basedir'];
        $uploads_url = $uploads['baseurl'];
        
        //check if flex uploads folder exists. if not, create it
        if (!file_exists("$uploads_dir/flex/fonts/")) {
            mkdir("$uploads_dir/flex/fonts", 0777, true);
        }

        foreach ($font_styles as $font_id => $font_style) {

            $parsed_font_style = self::generateFontStyle($font_id, $font_style);
            $font_family_id = str_replace(" ", "_" , strtolower($font_style['font_family']));
            $font_type = $font_style['font_type'];
            
            if($font_type === 'default_font') {
                $parsed_font_style['source'] = 'custom';
                // upload default fonts to flex uploads folder to avoid broken font after theme is potentially deleted
                if (!isset($stylekit_fonts[$font_family_id])) {
                    $font_data = $font_style['font_url'][0];

                    $font_name = $font_data['name'];
                    $font_url = $font_data['url'];

                    if(strpos($font_data['url'], 'demo.flothemes') !== false || strpos($font_data['url'], 'demo.stage.flosites') !== false) {
                        if ( strpos($font_data['url'], '/app/') === false ) {
                            $font_url_params = explode('/', $font_data['url']);
                            unset($font_url_params[3]);
                            $font_url =  implode('/', $font_url_params );
                            $font_url = str_replace('wp-content', 'app', $font_url);
                        }   
                    }
                    
                    $ext = $font_data['format'];
                    
                    $font_filename = str_replace(' ', '-', $font_name) . '.' . $ext;

                    $upload_url = "$uploads_dir/flex/fonts/$font_filename";

                    $font_req = wp_remote_get($font_url);
                    
                    if(!is_wp_error($font_req) && isset($font_req['body'])) {
                        $font_content = $font_req['body'];
                    } else {
                        $font_content = file_get_contents($font_url);
                    }

                    file_put_contents("$uploads_dir/flex/fonts/$font_filename", $font_content);

                    //make url for downloaded file and update link
                    $files = $font_style['font_url'];
                    $url = "$uploads_url/flex/fonts/$font_filename";
                    $files[0]['url'] = $url;

                    $stylekit_fonts[$font_family_id] = [
                        'id' => $font_family_id,
                        'name' => $font_style['font_family'],
                        'files' => $files,
                    ];
                }
            } elseif($font_type === 'custom_font') {

                // for custom fonts keep existing font url, it's most likely already located in some uploads folder
                // if font face url is from typekit, we need to put it in a different array
                $is_typekit = false;
                if(
                    isset($font_style['font_url']) && 
                    is_array($font_style['font_url']) && 
                    sizeof($font_style['font_url']) && 
                    isset($font_style['font_url'][0]['url'])
                ) {
                    $font_first_url = $font_style['font_url'][0]['url'];
                    $is_typekit = strpos($font_first_url, "use.typekit.net") !== false;
                }

                if($is_typekit) {
                    $parsed_font_style['source'] = 'typekit';
                
                    if (!isset($typekit_fonts[$font_family_id])) {
                        $typekit_font_face = '@font-face{';
                        $typekit_font_face .= 'font-family: "'.$font_style['font_family'].'";';
                        $typekit_font_face .= 'src:url('.$font_first_url.')';
                        $typekit_font_face .= '}';

                        $typekit_data = [
                            'family' => $font_style['font_family'],
                            'kind' => 'flofont:typekit',
                            'css' => $typekit_font_face,
                            'fontStyle' => 'normal',
                            'fontWeight' => 'normal',
                        ];
                        $typekit_fonts[$font_family_id] = $typekit_data;
                    }
                } else {
                    $parsed_font_style['source'] = 'custom';
                
                    // if local font file, push to custom fonts array
                    if (!isset($custom_fonts[$font_family_id])) {
                        $custom_fonts[$font_family_id] = [
                            'id' => $font_family_id,
                            'name' => $font_style['font_family'],
                            'files' => $font_style['font_url'],
                        ];
                    }
                }
                
            } elseif($font_type === 'google_font') {
                $parsed_font_style['source'] = 'gfonts';
                $gFontName = $font_style['font_url'][0]['name'];
                if(!isset($google_font_names[$gFontName])) {
                    $google_font_names[$gFontName] = $gFontName;
                }
            }

            $parsed_font_styles[$font_id] = $parsed_font_style;
            if($are_custom) {
                $parsed_font_styles[$font_id]['author'] = 'custom';
            }
        }

        return [
            'font_styles' => $parsed_font_styles,
            'stylekit_fonts' => $stylekit_fonts,
            'custom_fonts' => $custom_fonts,
            'google_font_names' => $google_font_names,
            'typekit_fonts' => $typekit_fonts,
        ];
    }

    public static function generateGFontsUrl($font_names_arr = []) {
        // exit early if no fonts are provided
        if(!sizeof($font_names_arr)) return "";

        $url = "https://fonts.googleapis.com/css?family=";
        foreach($font_names_arr as $index => $font_name) {
            $font_names_arr[$index] = str_replace(' ', '+', $font_name);
        }
        $joinedNames = implode('|', $font_names_arr);
        return $url . $joinedNames;
    }

    public static function generate_custom_data($theme_name, $font_styles) {
        $new_stylekit = [
            "fonts"       => [],
            "colors"      => [],
            "generalInfo" => [
                "name" => $theme_name,
                "id" => "custom-" . uniqid(),
                "customFonts" => [],
                "gFontsUrl" => "",
            ]
        ];

        $theme_defaults = $font_styles['theme_defaults'];
        $theme_defaults_data = self::parseFontStyles($theme_defaults);

        $stylekit_font_styles = $theme_defaults_data['font_styles'];
        $stylekit_fonts = $theme_defaults_data['stylekit_fonts'];
        $custom_fonts = $theme_defaults_data['custom_fonts'];
        $google_font_names = $theme_defaults_data['google_font_names'];
        $typekit_fonts = $theme_defaults_data['typekit_fonts'];

        // update custom related options here
        $flex_user_data = get_option('flex_user_data');
        if(empty($flex_user_data)) $flex_user_data = [];

        // update typekit fonts if any found
        $flex_typekit_manifest = get_option('flex_typekit_manifest');
        if(empty($flex_typekit_manifest)) $flex_typekit_manifest = [];

        if(isset($font_styles['user_specified'])) {
            $user_specified = $font_styles['user_specified'];
            $user_specified_data = self::parseFontStyles($user_specified, true);
            $stylekit_fonts = array_merge($stylekit_fonts, $user_specified_data['stylekit_fonts']);

            if(sizeof($user_specified_data['font_styles'])) {
                $flex_user_data['customFontGroups'] = $user_specified_data['font_styles'];
            }

            if(sizeof($user_specified_data['custom_fonts'])) {
                $custom_fonts = array_merge($custom_fonts, $user_specified_data['custom_fonts']);
            }

            if(sizeof($user_specified_data['google_font_names'])) {
                $flex_user_data['gFontsUrl'] = self::generateGFontsUrl($user_specified_data['google_font_names']);
            }

            if(sizeof($user_specified_data['typekit_fonts'])) {
                $typekit_fonts = array_merge($typekit_fonts, $user_specified_data['typekit_fonts']);
            }

        }

        if(sizeof($custom_fonts)) {
            $flex_user_data['customUserFonts'] = $custom_fonts;
        }

        if(sizeof($flex_user_data)) {
            update_option('flex_user_data', $flex_user_data);
        }

        if(sizeof($typekit_fonts)) {
            $flex_typekit_manifest = array_values($typekit_fonts);
            update_option('flex_typekit_manifest', $flex_typekit_manifest);
        }

        $new_stylekit['fonts'] = $stylekit_font_styles;
        $new_stylekit['generalInfo']['customFonts'] = $stylekit_fonts;
        $new_stylekit['generalInfo']['gFontsUrl'] = self::generateGFontsUrl($google_font_names);

        $acf_color_list = Flex_Builder_Data::getAcfColorsData();
        foreach ($acf_color_list['flex_stylekit_color_list'] as $color_id => $color_value) {
            $new_stylekit['colors'][$color_id] = [
                'id' => $color_id,
                'name' => $acf_color_list['flex_stylekit_color_labels'][$color_id],
                'value' => $color_value
            ];
        }
        
        return $new_stylekit;
    }

    public static  function generate_custom_manifest($custom_stylekit) {
        $custom_manifest = [
            'name' => $custom_stylekit['generalInfo']['name'],
            'id' => $custom_stylekit['generalInfo']['id'],
            'customFonts' => $custom_stylekit['generalInfo']['customFonts'],
            'timestamp' => time(),
            'preview' => [
                'colors' => [
                    'scheme_1/background/accent' => $custom_stylekit['colors']['scheme_1/background/accent']['value'],
                    'scheme_1/background/default' => $custom_stylekit['colors']['scheme_1/background/default']['value'],
                    'scheme_1/text/accent' => $custom_stylekit['colors']['scheme_1/text/accent']['value'],
                    'scheme_1/text/default' => $custom_stylekit['colors']['scheme_1/text/default']['value'],
                    'scheme_2/background/accent' => $custom_stylekit['colors']['scheme_2/background/accent']['value'],
                    'scheme_2/background/default' => $custom_stylekit['colors']['scheme_2/background/default']['value'],
                    'scheme_2/text/accent' => $custom_stylekit['colors']['scheme_2/text/accent']['value'],
                    'scheme_2/text/default' => $custom_stylekit['colors']['scheme_2/text/default']['value']
                ],
                'fonts' => [
                    'second_level/subtitle_1' => $custom_stylekit['fonts']['second_level/subtitle_1']['fontFamily'],
                    'second_level/paragraph' => $custom_stylekit['fonts']['second_level/paragraph']['fontFamily'],
                    'title_1/medium' => $custom_stylekit['fonts']['title_1/medium']['fontFamily'],
                    'third_level/overline_2' => $custom_stylekit['fonts']['third_level/overline_2']['fontFamily']
                ]
            ]
        ];

        return $custom_manifest;
    }

    public static function transform_old_data($theme_name, $font_data) {
        $all_installed_stylekits = [];
        $custom_manifests = [];
        $stylekits_names = [];

        if (is_string($font_data['font_styles'])) {
            $font_styles = json_decode($font_data['font_styles'], true);
        } else {
            $font_styles = (array)$font_data['font_styles'];
        }

        $custom_stylekit = self::generate_custom_data($theme_name, $font_styles);
        $custom_manifest = self::generate_custom_manifest($custom_stylekit);

        $custom_stylekit_id = $custom_stylekit['generalInfo']['id'];
        $all_installed_stylekits[$custom_stylekit_id] = $custom_stylekit;
        $custom_manifests[$custom_stylekit_id] = $custom_manifest;
        $stylekits_names[$custom_stylekit_id] = [
            'id' => $custom_stylekit_id,
            'name' => $custom_manifest['name']
        ];

        return [
            'td_active_name' => $custom_stylekit_id,
            'td_active_stylekits_names' => $stylekits_names,
            'td_custom_manifests' => $custom_manifests,
            'td_all_stylekits_obj' => $all_installed_stylekits
        ];
    }
}

// // DEV: ALWAYS INSTALL FONT DATA
// add_action('admin_init', function() {
//     $font_data = flex_get_field('flo-lyra-typography', 'options');
//     Flo_Flex_Builder_Update::transform_old_data("dev-test", $font_data);
// });
