<?php
namespace Formipay;
use Formipay\Traits\SingletonTrait;

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

class Thankyou {

    use SingletonTrait;

    private $form_id;
    private $order_data;
    private $order_details;
    private $form_submit;

    protected function __construct() {

        add_action( 'init',						            [$this, 'set_endpoint'], 999);
		add_filter( 'query_vars',				            [$this, 'set_query_vars'], 899);
        add_action( 'wp_enqueue_scripts',                   [$this, 'frontend_enqueue'] );
        add_filter( 'pre_get_document_title',               [$this, 'page_title'], 1012 );

		add_action( 'template_redirect',				    [$this, 'check_parse_query'], 999 );

        add_action( 'wp_ajax_request_access_link',          [$this, 'request_access_link'] );
        add_action( 'wp_ajax_nopriv_request_access_link',   [$this, 'request_access_link'] );

    }

    public function set_endpoint() {

        $slug = 'thankyou';
        $formipay_settings = get_option('formipay_settings');
        if(!empty($formipay_settings['thankyou_link'])){
            $slug = $formipay_settings['thankyou_link'];
        }

		add_rewrite_rule( 
            '^'.$slug.'/([^/]*)/?',
            'index.php?formipay-thankyou=1&formipay-token=$matches[1]',
            'top'
        );

        
    }

    public function set_query_vars($vars){

        $vars[] = 'formipay-thankyou';
        $vars[] = 'formipay-token';
        return $vars;

    }

    public function check_parse_query() {

        global $wp_query;

        $formipay_settings = get_option('formipay_settings');

        if(is_admin()) :
			return;
		endif;

        if(
            !is_admin() &&
			is_array($wp_query->query) &&
			array_key_exists('formipay-thankyou', $wp_query->query) &&
            true === boolval($wp_query->query['formipay-thankyou'])
        ) :


            $token_value = sanitize_text_field($wp_query->query['formipay-token']);
            $token_manager = new \Formipay\Token();

            // New token validation
            if ($token_data = $token_manager->validate($token_value)) {
                $this->form_id = $form_id = $token_data['form_id'];
                $this->order_id = $order_id = $token_data['order_id'];
                $token_manager->increment_usage($token_value);
            }
            else {
                wp_die('Invalid access token');
            }

            $this->order = $order = formipay_get_order($order_id);

            $this->order_details = $order['items'];
            $this->form_submit = $order['form_data'];

            $button_background_color = json_decode(formipay_get_post_meta($form_id, 'button_bg_color'), true );
            $button_text_color = json_decode(formipay_get_post_meta($form_id, 'button_text_color'), true );
            $button_border_color = json_decode( formipay_get_post_meta($form_id, 'button_border_color'), true );

            include_once FORMIPAY_PATH . 'public/templates/thank-you.php';
            exit;

        endif;

    }

    public function process_order_meta() {
        $order_meta = [];
        if(!empty($this->order['meta_data'])){
            foreach($this->order['meta_data'] as $meta_data){
                $key = $meta_data['name'];
                $value = $meta_data['value'];
                $order_meta[$key] = $value;
            }
        }
        return $order_meta;
    }

    public function access_method() {
        $order_meta = $this->process_order_meta();

        $access_method = 'magic_link';
        if(isset($order_meta['access_method'])) {
            $access_method = $order_meta['access_method'];
        }
        
        return $access_method;
    }

    public function frontend_enqueue() {

        global $wp_query;

        if(
			is_array($wp_query->query) &&
			array_key_exists('formipay-thankyou', $wp_query->query) &&
            true === boolval($wp_query->query['formipay-thankyou'])
        ) :

            wp_enqueue_style( 'bs-icons', FORMIPAY_URL . 'vendor/Bootstrap/bootstrap-icons.css', [], '1.11.1', 'all');
            wp_enqueue_style( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.css', [], '11.14.5', 'all');
            wp_enqueue_style( 'formipay-form-style', FORMIPAY_URL . 'public/assets/css/form-style.css', [], FORMIPAY_VERSION, 'all' );
            wp_enqueue_style( 'formipay-thankyou', FORMIPAY_URL . 'public/assets/css/thankyou.css', [], FORMIPAY_VERSION, 'all' );

            wp_enqueue_script( 'jquery-blockui', FORMIPAY_URL . 'vendor/jQuery-UI/jquery.blockUI.min.js', ['jquery'], '2.7.0', true);
            wp_enqueue_script( 'jquery-clipboard', FORMIPAY_URL . 'vendor/ClipboardJS/clipboard.min.js', ['jquery'], '2.0.11', true);
            wp_enqueue_script( 'sweetalert2', FORMIPAY_URL . 'vendor/SweetAlert2/sweetalert2.min.js', ['jquery'], '11.14.5', true);
            wp_enqueue_script( 'formipay-thankyou', FORMIPAY_URL . 'public/assets/js/thankyou.js', ['jquery'], FORMIPAY_VERSION, true );
            wp_enqueue_script( 'formipay-access-request', FORMIPAY_URL . 'public/assets/js/access-link-request.js', ['jquery'], FORMIPAY_VERSION, true );

            $order_id = $this->order['id'];

            wp_localize_script( 'formipay-thankyou', 'formipay_thankyou', [
                'ajax_url' => admin_url('admin-ajax.php'),
                'order_id' => $this->order_id,
                'access_method' => $this->access_method(),
                'email_validation' => [
                    'error' => [
                        'message' => __( 'Input a valid email address', 'formipay' )
                    ]
                ],
                'nonce' => wp_create_nonce('formipay-thankyou-nonce')
            ] );

        endif;

    }

    public function can_access() {

        $order_id = $this->order['id'];
        // $order_meta = $this->order['meta_data'];
        $order_meta = $this->process_order_meta();

        $order_ip_address = $order_meta['ip_address'];
        $order_user_agent = $order_meta['user_agent'];
        $order_device_type = $order_meta['device_type'];

        $current_ip_address = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['REMOTE_ADDR'])) : '';
        $current_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])) : '';
        $current_device_type = (isset($_SERVER['HTTP_USER_AGENT']) && strpos(sanitize_text_field(wp_unslash($_SERVER['HTTP_USER_AGENT'])), 'Mobile') !== false) ? 'Mobile' : 'Desktop';

        $can_access = false;

        if(
            $order_ip_address === $current_ip_address &&
            $order_user_agent === $current_user_agent &&
            $order_device_type === $current_device_type
        ) {

            $cookie = $this->get_cookie();
            
            if(
                !empty($order_meta['session_id']) && 
                !empty($cookie) && 
                isset($cookie[$order_id]) && $cookie[$order_id] == $order_meta['session_id']
            ){

                $can_access = true;

            }

        }

        return $can_access;

    }

    public function render_view() {
        $thankyou_content = formipay_get_post_meta($this->form_id, 'thankyou_screen_content');
        $formipay_order_statuses = formipay_order_status_list();
        $this_order_status = $formipay_order_statuses[ $this->order['status']];

        $buyer_name = '';
        if(!empty(formipay_get_post_meta($this->form_id, 'buyer_name'))){
            $buyer_name_field = formipay_get_post_meta($this->form_id, 'buyer_name');
            if(!empty($this->order['form_data'])){
                foreach($this->order['form_data'] as $_form_data){
                    if($_form_data['name'] == $buyer_name_field){
                        $buyer_name = $_form_data['value'];
                        break;
                    }
                }
            }
        }

        $shortcodes = [
            'buyer_name'        => $buyer_name,
            'product_name'      => get_the_title($this->form_id),
            'order_id'          => $this->order['id'],
            'order_date'        => $this->order['created_date'],
            'order_total'       => '<p data-copy-value="' . $this->order['total'] . '" style="margin-bottom: .25em;">' . formipay_price_format( $this->order['total'], $this->form_id ) . '</p>
                                    <button class="formipay-copy-button" data-copy-text="Copy" data-copied-text="Copied" data-not-copied-text="Not copied!" style="font-size: 14px;">
                                        <i class="bi bi-copy"></i>Copy
                                    </button>',
            'order_status'      => $this_order_status,
            'order_details'     => $this->render_order_details(),
            'form_submission'   => $this->render_form_submit()
        ];

        $shortcodes = apply_filters( 'formipay/thankyou/shortcodes', $shortcodes, $this->form_id, $this->order, 'thankyou' );
        
        $replacements = [];
        if(!empty($shortcodes)){
            foreach($shortcodes as $key => $value){
                $replacements['{{'.$key.'}}'] = $value;
            }
        }
        $thankyou_content = strtr($thankyou_content, $replacements);

        return $thankyou_content;
    }

    public function view_access() {

        ob_start();
        ?>

        <main class="formipay-thank-you" role="main">
            <section class="formipay-content-wrapper receipt" aria-label="Order Receipt">
                <div class="formipay-the-contents">
                <?php echo wp_kses($this->render_view(), formipay_thankyoupage_allowed_html()); ?>
                </div>
            </section>
            <?php if($this->access_items() !== '') { ?>
            <section class="formipay-content-wrapper receipt downloads" aria-label="Downloads">
                <div class="formipay-the-contents">
                    <?php echo $this->can_access() ? $this->access_items() : wp_kses($this->request_access(), formipay_thankyoupage_allowed_html()); ?>
                </div>
            </section>
            <?php } ?>
        </main>

        <?php
        $content = ob_get_contents();
        ob_end_clean();

        // echo $content;
        echo wp_kses($content, formipay_thankyoupage_allowed_html());
        // echo wp_kses_post( $content );

    }

    public function request_access() {

        $formipay_settings = get_option('formipay_settings');

        if($this->order['status'] !== 'completed') {
            return;
        }

        $active_media = [];

        if( formipay_get_post_meta($this->form_id, 'product_access_to_email') == 'on'){
            $active_media[] = 'email';
        }

        $active_media = apply_filters('formipay/order/access/active-media', $active_media, $this->form_id);

        ob_start();
        ?>
            <div class="request-thumbnail">
                <?php
                echo wp_get_attachment_image( $formipay_settings['thankyou_page_restriction_thumbnail'], 'full', false, [
                    'width' => '120'
                ] );
                ?>
            </div>
            <h2 id="access-request-heading"><?php echo esc_html($formipay_settings['thankyou_page_restriction_title']); ?></h2>
            <form action="" class="request-for-access">
                <div class="formipay-field-group" style="margin-bottom: 1em;">
                    <?php if($this->access_method() == 'magic_link') { ?>
                    <input type="text" name="access-pass-request" id="access-pass"
                        class="formipay-input"
                        value="" placeholder="Input <?php echo esc_html( implode('/', $active_media) ); ?>" required>
                    <p>
                        <?php echo 
                        esc_html(
                            str_replace('{{media}}', implode(',', $active_media) ,$formipay_settings['thankyou_page_restriction_message'])
                        );
                        ?>
                    </p>
                    <?php } elseif($this->access_method() == 'static_password') { ?>
                    <input type="password" name="access_password" id="access-pass"
                        class="formipay-input"
                        value="" placeholder="Input <?php echo esc_html( 'Password' ); ?>" required>
                    <?php } ?>
                </div>
                <button type="submit" id="request_access_to_media" class="formipay-submit-button" disabled>
                    <?php echo esc_html( $formipay_settings['thankyou_page_restriction_button'] ); ?>
                </button>
            </form>
        <?php

        $content = ob_get_contents();
        ob_end_clean();

        return $content;

    }

    public function request_access_link() {

        check_ajax_referer( 'formipay-thankyou-nonce', '_wpnonce' );

        $pass = isset($_REQUEST['pass']) ? sanitize_text_field( wp_unslash($_REQUEST['pass']) ) : '';
        $order_id = isset($_REQUEST['order']) ? intval($_REQUEST['order']) : 0;
        $method = isset($_REQUEST['method']) ? sanitize_text_field( wp_unslash($_REQUEST['method']) ) : '';

        $order = formipay_get_order($order_id);

        $formipay_order = new Formipay_Order();
        $formipay_get_order = $formipay_order->get($order_id);
        $order_meta_data = maybe_unserialize($formipay_get_order->meta_data);

        $valid = false;
        // validate pass
        if($method == 'magic_link'){
            $email_field_name = formipay_get_post_meta($order['form_id'], 'notification_email_buyer_recipient');
            // $email_purchase = $order['form_data'][$email_field_name];
            $email_purchase = '';
            foreach($order['form_data'] as $form_data){
                if($form_data['name'] == $email_field_name){
                    $email_purchase = $form_data['value'];
                    break;
                }
            }

            if($email_purchase !== $pass){
                wp_send_json( [
                    'title' => __( 'Wrong email!', 'formipay' ),
                    'message' => __( 'You must enter an email address that matches the email you used during purchase.', 'formipay' ),
                    'icon' => 'error'
                ] );
            }

            $valid = true;
        }
        
        if($method == 'static_password'){

            if(
                !empty($order_meta_data['access_password']) &&
                $pass !== $order_meta_data['access_password']
            ) {
                wp_send_json([
                    'title' => __( 'Password is invalid', 'formipay' ),
                    'message' => __( 'Please input a valid password to access this page.', 'formipay' ),
                    'icon' => 'error'
                ]);
            }

            $valid = true;

        }
        
        if(!$valid){
            wp_send_json([
                'title' => __( 'Not provided access method', 'formipay' ),
                'message' => __( 'Contact the web master for further information or try again.', 'formipay' ),
                'icon' => 'error'
            ]);
        }

        // $order_meta_data = $order['meta_data'];

        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '';
        $order_meta_data['session_id'] = uniqid();
        $order_meta_data['ip_address'] = isset($_SERVER['REMOTE_ADDR']) ? sanitize_text_field( wp_unslash($_SERVER['REMOTE_ADDR']) ) : '';
        $order_meta_data['user_agent'] = $user_agent;
        $order_meta_data['device_type'] = (strpos( $user_agent, 'Mobile') !== false) ? 'Mobile' : 'Desktop';

        $update = $formipay_order->update(
            $order['id'], 
            [
                'meta_data' => $order_meta_data
            ] 
        );

        if(is_wp_error( $update )){

            wp_send_json( [
                'title' => __( 'Failed!', 'formipay' ),
                'message' => __( 'Something\'s happened. Contact the web master for further information or try again.', 'formipay' ),
                'icon' => 'error'
            ] );

        }

        $cookie = $this->get_cookie();
        $cookie[$order_id] = $order_meta_data['session_id'];
        setcookie( 'fp_access', wp_json_encode($cookie), time() + 86400, '/', '', is_ssl(), true );

        if($method == 'magic_link'){
            do_action('formipay/notification/access/email', $order);
            wp_send_json( [
                'title' => __( 'Access Link Sent!', 'formipay' ),
                'message' => __( 'Check your Inbox (or maybe Spam) to find a new access link so you can get digital access of this purchase.', 'formipay' ),
                'icon' => 'success',
                'action' => 'idle'
            ] );
        }elseif($method == 'static_password') {
            wp_send_json( [
                'title' => __( 'Password is Valid!', 'formipay' ),
                'message' => __( 'You will be redirected to new link. Please wait.', 'formipay' ),
                'icon' => 'success',
                'action' => 'reload'
            ] );
        }

    }

    public function access_items() {

        $content = '';

        if($this->order['status'] == 'completed' && !empty( formipay_get_post_meta($this->form_id, 'product_accesses') ) ){
            // $downloads = json_decode( formipay_get_post_meta($this->form_id, 'product_access_downloads'), true );
            $accesses = explode(',', formipay_get_post_meta($this->form_id, 'product_accesses'));
            if(!empty($accesses)){
                ob_start();
                foreach($accesses as $access){

                    $type = formipay_get_post_meta( $access, 'access_type' );
                    $button_text = formipay_get_post_meta( $access, 'button_text' );

                    if($type == 'download'){
                        $source = formipay_get_post_meta( $access, 'access_download_source' );
                        if($source == 'external'){
                            $link = formipay_get_post_meta( $access, 'access_url' );
                            $filesize = formipay_get_post_meta( $access, 'details_filesize' );
                        }elseif($source == 'wp_media'){
                            $attachment_id = formipay_get_post_meta( $access, 'access_attachment' );
                            $link = wp_get_attachment_url($attachment_id);
                            $filesize = size_format( filesize( get_attached_file( $attachment_id ) ), 2 );
                        }
                    }elseif($type == 'redirect'){
                        $link = formipay_get_post_meta( $access, 'access_redirect_url' );
                        $attachment_id = 0;
                        $filesize = '';
                    }

                    $image = formipay_attachment_icon($attachment_id);
                    if(!empty(formipay_get_post_meta($access, 'details_icon'))){
                        $image = wp_get_attachment_image(formipay_get_post_meta($access, 'details_icon'), 'thumbnail', false, [
                            'width' => '36',
                            'height' => '36'
                        ]);
                    }

                    ?>
                    <div class="formipay-single-download">
                        <?php echo wp_kses_post($image); ?>
                        <div class="formipay-download-information">
                            <div class="formipay-file-info">
                                <span class="formipay-file-title">
                                    <?php echo esc_html(get_the_title( $access )); ?>
                                </span>
                                <?php if(false !== formipay_get_post_meta($access, 'details_short_description')) { ?>
                                    <p class="formipay-access-item-description">
                                        <?php echo esc_html(formipay_get_post_meta($access, 'details_short_description')); ?>
                                    </p>
                                <?php } ?>
                                <?php if( '' !== $filesize){ ?>
                                    <span class="formipay-file-size">
                                        <?php echo esc_html($filesize); ?>
                                    </span>
                                <?php } ?>
                            </div>
                            <a id="formipay-download-<?php echo esc_attr($access) ?>" class="formipay-download-button formipay-submit-button" href="<?php echo esc_url($link) ?>" <?php echo $type == 'download' ? 'download' : 'target="_blank"' ?>>
                                <?php echo esc_html($button_text); ?>
                            </a>
                        </div>
                    </div>
                    <?php

                }

                $content = '<div class="formipay-downloads">'.ob_get_contents().'</div>';
                ob_end_clean();

            }
        }

        return $content;

    }

    public function page_title($title) {

        global $wp_query;

        if(
			is_array($wp_query->query) &&
			array_key_exists('formipay-thankyou', $wp_query->query) &&
            true === boolval($wp_query->query['formipay-thankyou'])
        ) :

            $token = explode(':::', base64_decode($wp_query->query['formipay-token']));
            $form_id = $token[0];
            $order_id = $token[1];

            $title = 'Thankyou' . ' for your order #' . $order_id;

        endif;

        return $title;

    }

    public function render_order_details() {

        ob_start();
        if(!empty($this->order_details)){
        ?>
        <table id="order-details">
            <tbody>
                <?php
                foreach($this->order_details as $detail){
                    $qty = '';
                    if(isset($detail['qty'])){
                        $qty = ' <i class="bi bi-x"></i> '.$detail['qty'];
                    }
                    ?>
                        <tr>
                            <th><?php echo wp_kses_post($detail['item']) . wp_kses_post($qty); ?></th>
                            <td><?php echo esc_html(formipay_price_format($detail['subtotal'], $this->form_id)); ?></td>
                        </tr>
                    <?php
                }
                ?>
                <tr>
                    <th><?php echo esc_html__( 'Total', 'formipay' ); ?></th>
                    <td><b><?php echo esc_html(formipay_price_format($this->order['total'], $this->form_id)); ?></b></td>
                </tr>
            </tbody>
        </table>
        <?php
        }
        $content = ob_get_contents();
        ob_get_clean();

        return $content;
    }

    public function render_form_submit() {
        ob_start();
        if(!empty($this->form_submit)){
            $field_config = formipay_get_post_meta($this->form_id, 'formipay_settings');
            ?>
            <table id="order-submission-details">
                <tbody>
                    <tr>
                        <th><?php echo esc_html__('Product', 'formipay'); ?></th>
                        <td><?php echo esc_html(get_the_title($this->form_id)); ?></td>
                    </tr>
                    <?php
                    $skip_row = array(
                        'form_id', 'payment', 'order_id', 'order_status', 'grand_total', 'order_date'
                    );
                    foreach($this->form_submit as $field){
                        // $field_label = $field_config['fields'][$field_name.'_config']['label'];
                        $field_name = $field['name'];
                        $field_value = $field['value'];
                        if(in_array($field_name, $skip_row)){
                            continue;
                        }
                        if(empty($field_value)){
                            continue;
                        }
                        switch ($field_name) {
                            case 'form_id':
                                $field_label = esc_html__( 'Form ID', 'formipay' );
                                break;
                            case 'qty':
                                $field_label = esc_html__( 'Quantity', 'formipay' );
                                break;
                            case 'coupon_code':
                                $field_label = esc_html__( 'Coupon Discount', 'formipay' );
                                break;
                            case 'payment':
                                $field_label = esc_html__( 'Payment', 'formipay' );
                                break;
                            case 'payment_gateway':
                                $field_label = esc_html__( 'Payment Method', 'formipay' );
                                // $field_value = ucwords(str_replace('_', ' ', $field_value));
                                $field_value = $field_value == 'cod' ? 'Cash on Delivery' : ucwords( str_replace(['-','_'], ' ', $field_value) );
                                break;
                            case 'order_id':
                                $field_label = esc_html__( 'Order ID', 'formipay' );
                                break;
                            case 'grand_total':
                                $field_label = esc_html__( 'Grand Total', 'formipay' );
                                $field_value = esc_html(formipay_price_format($field_value, $this->form_id));
                                break;
                            case 'order_status':
                                $field_label = esc_html__( 'Order Status', 'formipay' );
                                break;
                            case 'order_date':
                                $field_label = esc_html__( 'Order Date', 'formipay' );
                                break;
                            
                            default:
                                // $field_label = $field_config['fields'][$field_name.'_config']['label'];
                                if(is_array($field_value)){
                                    $field_value = $field_value['value'];
                                }
                                if(filter_var($field_value, FILTER_VALIDATE_EMAIL)){
                                    $field_value = $field_value;
                                }elseif(strpos($field_value, ',') !== false){
                                    $values = explode(',', $field_value);
                                    $field_value = '';
                                    foreach($values as $value){
                                        $field_value .= '<span class="checkbox-span">'.$value.'</span> ';
                                    }
                                }else{
                                    $field_value = ucwords( str_replace(['-','_'], ' ', $field_value) );
                                }
                                break;
                        }
                        
                        ?>
                            <tr>
                                <th><?php echo esc_html($field_label) ?></th>
                                <td><?php echo wp_kses_post($field_value) ?></td>
                            </tr>
                        <?php
                    }
                    ?>
                </tbody>
            </table>
            <?php
        }
        $content = ob_get_contents();
        ob_get_clean();

        return $content;
    }

    public function get_cookie() {
        $cookie = [];
        if (!empty($_COOKIE['fp_access'])) {
            // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
            $raw_value = wp_unslash($_COOKIE['fp_access']);

            $decoded = json_decode($raw_value, true);

            if (is_array($decoded)) {
                $cookie = array_map('sanitize_text_field', $decoded);
            }
        }
        return $cookie;
    }

}