<?php

namespace EAddonsPdf\Core\Utils;

use EAddonsForElementor\Core\Utils;

/**
 * Description of Pdf Utils
 *
 */
class Pdf {
    
    public static function fix_html($pdf_html = '', $settings = array()) {
        
        // strip forms
        $tmp = explode('<form ', $pdf_html);
        if (count($tmp) > 1) {
            foreach ($tmp as $key => $aform) {
                if ($key) {
                    list($form, $other) = explode('</form>', $aform, 2);
                    $pdf_html_tmp .= $other;
                } else {
                    $pdf_html_tmp = $aform;
                }
            }
            $pdf_html = $pdf_html_tmp;
        }
        
        if (!empty($settings['e_pdf_section_page'])) {
            $pdf_html = preg_replace('/ elementor-top-section/', '', $pdf_html, 1);
            $pdf_html = self::add_inline_assets('.elementor-top-section { page-break-before: always; }.elementor-top-section:first-child { page-break-before: no; }', 'style', $pdf_html); 
        }
        
        // hide Button PDF
        $pdf_html = str_replace(' elementor-widget-button_pdf', ' elementor-widget-button_pdf elementor-hidden', $pdf_html);
        
        // try to fix Divider
        $pdf_html = str_replace('<div class="elementor-divider">', '<div class="elementor-divider"><hr>', $pdf_html);
        
        return $pdf_html;
    }
    
    public static function fix_css($pdf_html = '', $post_id = null, $styles = 'unstyled', $target = 'pdf') {

        // TODO?
        //$stylesheet = file_get_contents('style.css');
        //$mpdf->WriteHTML($stylesheet, \Mpdf\HTMLParserMode::HEADER_CSS);

        if ($styles != 'unstyled') {
            // add CSS
            $css = Utils::get_extra_css($post_id, ($styles == 'all'));
 
            //var_dump($css); die();            
            if ($post_id) {
                $document = \Elementor\Plugin::$instance->documents->get_doc_for_frontend($post_id);
                if ($document && $document->is_built_with_elementor()) {
                    $data = $document->get_elements_data();
                    foreach ($data as $element_data) {
                        $section = \Elementor\Plugin::$instance->elements_manager->create_element_instance($element_data);
                        if ($section) {
                            foreach ( $section->get_children() as $col ) {
                                if ($col->get_settings('_inline_size')) {
                                    $_inline_size = floatval($col->get_settings('_inline_size'));
                                    $_inline_size = $_inline_size - 0.001;
                                    $css .= '.elementor-column.elementor-col-'.$col->get_settings('_column_size').'.elementor-element-'.$col->get_id().'{ width: '.$_inline_size.'%; }';
                                } else {
                                    if ($col->get_settings('_column_size')) {
                                        $_inline_size = floatval($col->get_settings('_column_size'));
                                        $_inline_size = $_inline_size - 0.001;
                                        $css .= '.elementor-column.elementor-col-'.$col->get_settings('_column_size').'.elementor-element-'.$col->get_id().'{ width: '.$_inline_size.'%; }';
                                    }
                                }
                            }
                        }
                    }
                }
            }
            
            // hide Button PDF
            //$pdf_html = self::add_inline_assets('.elementor-widget-button_pdf { display: none !important; }', 'style', $pdf_html);
            //$css .= '.elementor-widget-button_pdf { display: none !important; }';


            if ($pdf_html) {
                $cssToInlineStyles = new \TijsVerkoyen\CssToInlineStyles\CssToInlineStyles();
                $pdf_html = $cssToInlineStyles->convert(
                        $pdf_html,
                        $css
                );
            }

            $pdf_html = str_replace('font-weight: bolder;', 'font-weight: bold;', $pdf_html);
            //var_dump($pdf_html); die();
        }

        return $pdf_html;
    }

    public static function add_extra_fonts($params) {

        //https://mpdf.github.io/fonts-languages/fonts-in-mpdf-7-x.html
        $defaultConfig = (new \Mpdf\Config\ConfigVariables())->getDefaults();
        $fontDirs = $defaultConfig['fontDir'];

        $defaultFontConfig = (new \Mpdf\Config\FontVariables())->getDefaults();
        $fontData = $defaultFontConfig['fontdata'];

        $fontDir = $params['tempDir'] . DIRECTORY_SEPARATOR . 'font';
        if (is_dir($fontDir)) {
            $fonts = glob($fontDir . DIRECTORY_SEPARATOR . '*/*.ttf');

            foreach ($fonts as $font) {
                $dir = dirname($font);
                $fontDirs = array_merge($fontDirs, [
                    $dir,
                ]);
                $tmp = explode(DIRECTORY_SEPARATOR, $dir);
                $name = sanitize_title(end($tmp));
                $tmp = $fontData + [
                    $name => [
                        'R' => basename($font),
                    //'I' => basename($font),
                    //'B' => basename($font),
                    //'BI' => basename($font),
                    //'useOTL' => 0xFF,
                    //'useKashida' => 75,
                    ],
                ];
                $fontData = $tmp;
                //$params['default_font'] = $name;
            }
        }

        $fontsOpt = get_option('elementor_fonts_manager_fonts');
        //var_dump($fontsOpt); die();
        if (!empty($fontsOpt)) {
            foreach ($fontsOpt as $name => $font) {
                $name = sanitize_title($name);
                $tmp = explode(".ttf')", $font['font_face']);
                if (count($tmp) == 2) {
                    $tmp = reset($tmp);
                    $tmp = explode("url('", $tmp);
                    $tmp = end($tmp);
                    $url = $tmp . '.ttf';
                    $font = Utils::url_to_path($url);
                    //var_dump($font); die();
                    $dir = dirname($font);
                    $fontDirs = array_merge($fontDirs, [
                        $dir,
                    ]);
                    $tmp = $fontData + [
                        $name => [
                            'R' => basename($font),
                        //'I' => basename($font),
                        //'B' => basename($font),
                        //'BI' => basename($font),
                        //'useOTL' => 0xFF,
                        //'useKashida' => 75,
                        ],
                    ];
                    $fontData = $tmp;
                }
            }
        }
        //var_dump($fontDirs); var_dump($fontData); die();
        $params['fontdata'] = $fontData;
        $params['fontDir'] = $fontDirs;

        return $params;
    }

    // remove the elementor Template main wrappers (added by "print_elements_with_wrapper")
    public static function template_unwrap($html = '') {

        $tmp = explode('<body>', $html, 2);
        $html = end($tmp);

        $tmp = explode('<body ', $html, 2);
        if (count($tmp) > 1) {
            $tmp = end($tmp);
            list($a, $html) = explode('>', $tmp, 2);
        }

        $tmp = explode('</body>', $html, 2);
        $html = reset($tmp);

        $html = trim($html);

        if (strpos($html, 'elementor-section-wrap') !== false) {
            list($tmp, $html) = explode('elementor-section-wrap', $html, 2);
            //var_dump($tmp);
            $tmp = explode('<', $tmp);
            array_pop($tmp);
            array_pop($tmp);
            array_pop($tmp);

            $pre = implode('<', $tmp);
            //var_dump($pre); die();
            list($tmp, $html) = explode('>', $html, 2);
            $html = $pre . $html;

            // remove extra style block
            $tmp = explode('<section', $html, 2);
            if (count($tmp) == 2) {
                list($a, $html) = $tmp;
                $html = '<section' . $html;
            }

            $divs = 2; // 3;
            for ($i = 0; $i < $divs; $i++) {
                $pos = strrpos($html, '</div>');
                if ($pos !== false) {
                    $html = substr_replace($html, '', $pos, strlen('</div>'));
                }
            }
        }
        $html = trim($html);
        return $html;
    }

    public static function add_inline_assets($assets, $type = 'style', $html = '') {
        $code = '<' . $type . '>' . $assets . '</' . $type . '>';
        if (strpos($html, '</body>')) {
            $html = str_replace('</body>', $code . '</body>', $html);
        } else {
            $html .= $code;
        }
        return $html;
    }

    public static function get_params($params = array(), $settings = array()) {
        
        if (empty($params)) {
            $size = empty($settings['e_form_pdf_size']) ? $settings['e_pdf_button_size'] : $settings['e_form_pdf_size'];
            $params = array(
                'mode' => 'utf-8',
                'format' => $size,
                'orientation' => ($settings['e_pdf_orientation'] == 'portrait' ? 'P' : 'L'),
                'tempDir' => WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'mpdf',
                    //'default_font' => 'dejavusans',
            );        
        }
        $params = self::add_extra_fonts($params);
        
        if (!empty($settings['e_pdf_dpi'])) {
            $params['dpi'] = intval($settings['e_pdf_dpi']);
            $params['img_dpi'] = intval($settings['e_pdf_dpi']);
        }

        if (isset($settings['e_pdf_margin']['top']) && $settings['e_pdf_margin']['top'] != '') {
            //$params['margin-top'] = intval($settings['e_pdf_margin']['top']); 
            $params['mgt'] = intval($settings['e_pdf_margin']['top']);             
        }
        if (isset($settings['e_pdf_margin']['bottom']) && $settings['e_pdf_margin']['bottom'] != '') {
            $params['mgb'] = intval($settings['e_pdf_margin']['bottom']);
        }
        if (isset($settings['e_pdf_margin']['right']) && $settings['e_pdf_margin']['right'] != '') {
            $params['mgr'] = intval($settings['e_pdf_margin']['right']);
        }        
        if (isset($settings['e_pdf_margin']['left']) && $settings['e_pdf_margin']['left'] != '') {
            $params['mgl'] = intval($settings['e_pdf_margin']['left']);
        }
        if (!empty($settings['e_pdf_header_margin'])) {
            $params['margin_header'] = intval($settings['e_pdf_header_margin']);
        }
        if (!empty($settings['e_pdf_footer_margin'])) {
            $params['margin_footer'] = intval($settings['e_pdf_footer_margin']);
        }
        //$params['setAutoTopMargin'] = 'pad';
        if (isset($settings['e_pdf_margin']['top']) && $settings['e_pdf_margin']['top'] != '') {
            $params['nonPrintMargin'] = 0;
        }
        //
        //var_dump($params); die();
        return $params;
    }

    public static function get_dynamic_data($string, $post = false) {
        $string = str_replace('[date|Y]', date('Y'), $string);
        $string = str_replace('[date|m]', date('m'), $string);
        $string = str_replace('[Y]', date('Y'), $string);
        $string = str_replace('[m]', date('m'), $string);
        $string = str_replace('[date|U]', date('U'), $string);
        $string = str_replace('[U]', date('U'), $string);
        if ($post) {
            $string = str_replace('[post:name]', $post->post_name, $string);
            $string = str_replace('{{post.post_name}}', $post->post_name, $string);
            //$string = sanitize_key($string);
        }        
        $string = Utils::get_dynamic_data($string, $post, 'post');
        $string = sanitize_title($string);
        $string = urldecode($string);
        return $string;
    }

    public static function set_bg($mpdf, $settings) {
        if (!empty($settings['e_pdf_background_color'])) {
            $mpdf->SetDefaultBodyCSS('background-color', $settings['e_pdf_background_color']);
        }

        if (!empty($settings['e_pdf_background_image']['id'])) {
            $img_url = $settings['e_pdf_background_image']['url'];
            $mpdf->SetDefaultBodyCSS('background', "url(" . $img_url . ")");
            $mpdf->SetDefaultBodyCSS('background-image-resize', 6);
        }

        self::set_watermark($mpdf, $settings);
    }

    public static function set_watermark($mpdf, $settings) {
        /* WATERMARK */
        $alpha = 0.2;
        if (!empty($settings['e_pdf_watermark_opacity'])) {
            $alpha = $settings['e_pdf_watermark_opacity'];
        }
        if (!empty($settings['e_pdf_watermark_text'])) {
            if (!empty($settings['e_pdf_watermark_rotation'])) {
                $GLOBALS['rotate'] = $settings['e_pdf_watermark_rotation'];
            }
            $mpdf->SetWatermarkText(trim($settings['e_pdf_watermark_text']), $alpha);
            $mpdf->showWatermarkText = true;
            /* if (!empty($settings['watermark_font'])) {
              $mpdf->watermark_font = $settings['watermark_font'];
              } */
        }        
        if (!empty($settings ['e_pdf_watermark_image']['id'])) {
            $img_url = $settings['e_pdf_watermark_image']['url'];
            $watermark_img_dim = 'D';
            if (!empty($settings['e_pdf_watermark_image_size'])) {
                switch ($settings['e_pdf_watermark_image_size']) {
                    case 'P':
                        $watermark_img_dim = 'P';
                        break;
                    case 'F':
                        $watermark_img_dim = 'F';
                        break;
                    case 'INT':
                        $watermark_img_dim = $settings['water_img_dim_int'];
                        $watermark_img_dim = (int) $watermark_img_dim;
                        break;
                    case 'array':
                        $watermark_img_dim = array($settings['e_pdf_watermark_image_size_width'], $settings['e_pdf_watermark_image_size_height']);
                        break;
                }
            }
            $watermark_pos = 'P';
            if (!empty($settings['e_pdf_watermark_image_position'])) {
                switch ($settings['e_pdf_watermark_image_position']) {
                    case 'F':
                        $watermark_pos = 'F';
                        break;
                    case 'array':
                        $watermark_pos = array($settings['e_pdf_watermark_image_position_x'], $settings['e_pdf_watermark_image_position_y']);
                        break;
                }
            }            
            $img_url = Utils::url_to_path($img_url);            
            //var_dump($img_url); die();            
            $mpdf->SetWatermarkImage($img_url, $alpha, $watermark_img_dim, $watermark_pos);
            $mpdf->showWatermarkImage = true;
        }
    }
    
    public static function extra_configuration($mpdf, $settings = array()) {
        // fix Hebrew
        $mpdf->autoScriptToLang = true;       
        $mpdf->autoLangToFont = !empty($settings['e_pdf_auto_lang_to_font']);
        
        if (!empty($settings['e_pdf_rtl'])) {        
            $mpdf->SetDirectionality('rtl');
        }

        //$mpdf->showImageErrors = true;
        //$mpdf->cacheTables = true;
        $mpdf->packTableData = true;
        
        // fix Flex layout with Float columns
        // https://mpdf.github.io/what-else-can-i-do/floating-blocks.html
        $mpdf->simpleTables = true;
    }

    public static function SetHTMLHeaderFooter($mpdf, $pdf_html, $settings, $fields = array(), $params = array()) {
        
        if (!empty($settings['e_pdf_header']) || !empty($settings['e_form_pdf_header'])) {
            $pdf_header = !empty($settings['e_pdf_header_txt']) ? $settings['e_pdf_header_txt'] : $settings['e_form_pdf_header_txt'];
            if (!empty($fields)) {
                $pdf_header = Utils::get_dynamic_data($pdf_header, $fields, 'form');                
            }
            $pdf_header = Utils::get_dynamic_data($pdf_header);
            if (!isset($params['mgt'])) {
                $mpdf->SetHTMLHeader($pdf_header);
            } else {
                $pdf_header = '<htmlpageheader name="myPdfHeader" style="display:none">'.$pdf_header.'</htmlpageheader>';
                $pdf_header_style = '@page { header: html_myPdfHeader; }';
                //$pdf_html = self::add_inline_assets($pdf_header_style, 'style', $pdf_html);
                $mpdf->WriteHTML($pdf_header_style, \Mpdf\HTMLParserMode::HEADER_CSS);
                $pdf_html = $pdf_header.$pdf_html;
            }
        }


        //$mpdf->SetHTMLFooter();
        if (!empty($settings['e_pdf_footer']) || !empty($settings['e_form_pdf_footer'])) {
            $pdf_footer = !empty($settings['e_pdf_footer_txt']) ? $settings['e_pdf_footer_txt'] : $settings['e_form_pdf_footer_txt'];
            if (!empty($fields)) {
                $pdf_footer = Utils::get_dynamic_data($pdf_footer, $fields, 'form');                
            }
            $pdf_footer = Utils::get_dynamic_data($pdf_footer);
            if (!isset($params['mgb'])) {
                $mpdf->SetHTMLFooter($pdf_footer);
            } else {
                $pdf_footer = '<htmlpagefooter name="myPdfFooter">'.$pdf_footer.'</htmlpagefooter>';
                $pdf_footer_style = '@page { footer: html_myPdfFooter; }';
                //$pdf_html = self::add_inline_assets($pdf_footer_style, 'style', $pdf_html);
                $mpdf->WriteHTML($pdf_footer_style, \Mpdf\HTMLParserMode::HEADER_CSS);
                $pdf_html = $pdf_footer.$pdf_html;
            }
        }
        
        return $pdf_html;
    }
        
    public static function WriteHTML($mpdf, $pdf_html) {
        
        //echo $pdf_html; die();            
        $pdf_html = self::convert_images($pdf_html);
        
        //echo $pdf_html; die();
        $mpdf->WriteHTML($pdf_html); return; 
        
        //$mpdf->WriteHTML('This is the beginning...', \Mpdf\HTMLParserMode::HTML_BODY, true, false);
        //$mpdf->WriteHTML('...this is the middle...', \Mpdf\HTMLParserMode::HTML_BODY, false, false);
        //$mpdf->WriteHTML('...and this is the end', \Mpdf\HTMLParserMode::HTML_BODY, false, true);
                
        $top_section_class = ' elementor-top-section ';
        $tmp = explode($top_section_class, $pdf_html);
        if (count($tmp) > 1) {
            $sections = array();
            $section_start = '<section class="elementor-section ';
            $section_close = '</section>';
            foreach ($tmp as $skey => $asection) {
                $tmp2 = explode($section_close, $asection);
                $last = array_pop($tmp2);
                $sect = implode($section_close, $tmp2).$section_close;
                if (empty($sections)) {
                    $sections[] = $sect;
                } else {
                    //$sections[] = $section_start.$top_section_class.$second;
                    $sections[] = $section_start.$top_section_class.$sect;
                }
                if ($skey == count($tmp)-1) {
                    //$sections[] = $last;
                    $mpdf->WriteHTML($last, \Mpdf\HTMLParserMode::HEADER_CSS);
                    
                }
            }
            //echo implode('',$sections); die();
            foreach ($sections as $skey => $section) {
                $mpdf->WriteHTML($section, \Mpdf\HTMLParserMode::HTML_BODY, !$skey, ($skey + 1 == count($sections)));
            }
        } else {
            $mpdf->WriteHTML($pdf_html);
        }
    }
    
    public static function convert_images($pdf_html) {
        // link image from url to path
        $split = 'src="' . ABSPATH;
        $pdf_html = str_replace('src="' . site_url() . '/', $split, $pdf_html);
        $tmp = explode('src="', $pdf_html);
        foreach ($tmp as $key => $aimg) {
            if ($key) {
                list($path, $other) = explode('"', $aimg, 2);
                if (substr($path, 0, strlen(ABSPATH)) === ABSPATH) {
                    if (file_exists($path)) {
                        $type = pathinfo($path, PATHINFO_EXTENSION);
                        $data = file_get_contents($path);
                        $base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
                        $pdf_html = str_replace('src="' . $path, 'src="' . $base64, $pdf_html);
                    } else {
                        $relpath = substr($path, strlen(ABSPATH));
                        $pdf_html = str_replace('src="' . $path, 'src="' . site_url() . '/' . $relpath, $pdf_html);
                    }
                }
            }
        }
        
        $split = "background-image: url('";
        $tmp = explode($split, $pdf_html);
        foreach ($tmp as $key => $aimg) {
            if ($key) {
                list($url, $other) = explode("');", $aimg, 2);
                $path = Utils::url_to_path($url);
                if (substr($path, 0, strlen(ABSPATH)) === ABSPATH) {
                    if (file_exists($path)) {
                        $type = pathinfo($path, PATHINFO_EXTENSION);
                        $data = file_get_contents($path);
                        $base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
                        $pdf_html = str_replace($split . $url, $split . $base64, $pdf_html);
                    }
                }
            }
        }
        
        //$pdf_html = str_replace('srcset="'.site_url(), 'nosrcset="'.site_url(), $pdf_html);  

        return $pdf_html;
    }

}
