<?php

namespace Salesloo;

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly.
}

use \Salesloo\Libraries\User_Info;

/**
 * Salesloo Frontend
 */
class Frontend
{
    public $classes;

    public $class = null;

    public $new_alpine_js_pages = [];

    /**
     * Instance.
     *
     * Hold salesloo frontend instance.
     *
     * @since 1.0.0
     * @access public
     */
    public static $instance = null;

    /**
     * Init
     * 
     * Initialize Salesloo Front end
     */
    public static function init()
    {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    /**
     * print head for member area
     */
    public function print_head()
    {
        $title = $this->component()->get_title();

        if (false === $title || empty($title)) {
            $page = __is_salesloo_page();
            $title = ucfirst($page);
            $title = str_replace('-', ' ', $title);
            $title = str_replace('_', ' ', $title);
        }

        if (is_singular('salesloo-file')) {
            $title = salesloo_data('title');
        }

        $title = apply_filters('salesloo/page/title', $title, __is_salesloo_page());
        $title = sprintf(__('%s | %s', 'salesloo'), $title, get_bloginfo('name'));

        echo '<title>' . $title . '</title>' . PHP_EOL;

        echo '<style>
            :root{
                --salesloo-primary-bg: ' . \salesloo_get_option('design_primary_bg', '#f4f7fc') . ';
                --salesloo-secondary-bg: ' . \salesloo_get_option('design_secondary_bg', '#ffffff') . ';
                --salesloo-primary-button-bg: ' . \salesloo_get_option('design_primary_button_bg', '#2564eb') . ';
                --salesloo-secondary-button-bg: ' . \salesloo_get_option('design_secondary_button_bg', '#4b5563') . ';
                --salesloo-primary-text-color: ' . \salesloo_get_option('design_primary_text_color', '#6b7280') . ';
                --salesloo-secondary-text-color: ' . \salesloo_get_option('design_secondary_text_color', '#9ca3af') . ';
                --salesloo-tertiary-text-color: ' . \salesloo_get_option('design_tertiary_text_color', '#ef4444') . ';
                --salesloo-quaternary-text-color: ' . \salesloo_get_option('design_quaternary_text_color', '#2564eb') . ';
            }
        </style>' . PHP_EOL;

        $styles = [
            [
                'id' => 'google-font',
                'source' => 'https://fonts.googleapis.com/css2?family=Nunito+Sans:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap',
            ],
            [
                'id' => 'salesloo',
                'source' => SALESLOO_ASSETS . 'css/style.min.css?v=' . SALESLOO_VERSION,
            ]
        ];

        $add_styles = $this->component()->enqueue_styles();
        $add_styles = apply_filters('salesloo/frontend/' . $this->component()->get_id() . '/styles', $add_styles);
        if ($add_styles && is_array($add_styles)) {
            $styles = array_merge($styles, $add_styles);
        }


        $salesloo_styles = apply_filters('salesloo/styles', $styles);

        foreach ((array)$salesloo_styles as $style) {

            if (!isset($style['source']) || !isset($style['id'])) continue;

            echo '<link rel="stylesheet" id="' . $style['id'] . '-css"  href="' . $style['source'] . '" media="all" />' . PHP_EOL;
        }

        echo stripslashes_deep(salesloo_get_option('head_script'));
    }

    /**
     * print head for member area
     */
    public function print_scripts()
    {

        $scripts = [
            [
                'id' => 'alpine-helpers',
                'source' => SALESLOO_ASSETS . 'js/alpine-helpers.js',
                'defer' => false
            ],
            [
                'id' => 'alpine',
                'source' => 'https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js',
                'defer' => false
            ],
            [
                'id' => 'salesloo',
                'source' => SALESLOO_ASSETS . 'js/app.js',
                'defer' => true
            ]
        ];

        if (in_array($this->component()->get_id(), $this->new_alpine_js_pages)) {
            $scripts = [
                [
                    'id' => 'salesloo',
                    'source' => SALESLOO_ASSETS . 'js/app.js',
                    'defer' => true
                ]
            ];
        } else {
            $scripts = [
                [
                    'id' => 'alpine-helpers',
                    'source' => SALESLOO_ASSETS . 'js/alpine-helpers.js',
                    'defer' => true
                ],
                [
                    'id' => 'alpine',
                    'source' => 'https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js',
                    'defer' => true
                ]
            ];
        }

        $add_scripts = $this->component()->enqueue_scripts();
        $add_scripts = apply_filters('salesloo/frontend/' . $this->component()->get_id() . '/scripts', $add_scripts);
        if ($add_scripts && is_array($add_scripts)) {
            $scripts = array_merge($add_scripts, $scripts);
        }

        $salesloo_scripts = apply_filters('salesloo/scripts', $scripts);

        foreach ((array)$salesloo_scripts as $script) {

            if (!isset($script['source'])) continue;

            $defer = '';
            if (isset($script['defer']) && true == $script['defer']) {
                $defer = 'defer';
            }
            echo '<script src="' . $script['source'] . '" ' . $defer . '></script>' . PHP_EOL;
        }

        echo stripslashes_deep(salesloo_get_option('footer_script'));
    }


    /**
     * Add query vars for handle salesloo endpoint.
     * 
     * @since    1.0.0
     * @return void
     */
    function add_query_vars($vars)
    {
        $vars[] = '__is_salesloo_page';
        $vars[] = '__salesloo_page';
        $vars[] = '__product';
        $vars[] = '__username';
        $vars[] = '__invoice';
        $vars[] = '__order';
        $vars[] = '__purchase_code';

        return $vars;
    }

    /**
     * Add endpoint.
     * Hooked via filter query_vars, priority 10
     * 
     * @since    1.0.0
     * @return void
     */
    public function add_endpoint()
    {

        $login    = salesloo_get_option('login_slug');
        $register = salesloo_get_option('register_slug');

        $dashboard   = 'dashboard';
        $affiliate   = 'affiliate';
        $transaction = 'transaction';
        $access      = 'access';


        add_rewrite_rule('^' . $register . '/?$', 'index.php?__salesloo_page=register', 'top');

        add_rewrite_rule('^' . $login . '/lostpassword/?$', 'index.php?__salesloo_page=login/reset-password', 'top');

        add_rewrite_rule('^' . $login . '/?$', 'index.php?__salesloo_page=login', 'top');

        /**dashboard url */
        add_rewrite_rule('^' . $dashboard . '/?$', 'index.php?__salesloo_page=dashboard', 'top');

        add_rewrite_rule('^product/?$', 'index.php?__salesloo_page=product', 'top');

        /**profile url */
        add_rewrite_rule('^profile/?$', 'index.php?__salesloo_page=profile', 'top');

        /** affiliate url */
        add_rewrite_rule('^' . $affiliate . '/product/([^/]+)/?$', 'index.php?__salesloo_page=affiliate/product/id&__product=$matches[1]', 'top');

        add_rewrite_rule('^' . $affiliate . '/product/?$', 'index.php?__salesloo_page=affiliate/product', 'top');

        add_rewrite_rule('^' . $affiliate . '/statistics/?$', 'index.php?__salesloo_page=affiliate/statistics', 'top');

        add_rewrite_rule('^' . $affiliate . '/commission/?$', 'index.php?__salesloo_page=affiliate/commission', 'top');

        add_rewrite_rule('^' . $affiliate . '/withdrawal/?$', 'index.php?__salesloo_page=affiliate/withdrawal', 'top');


        add_rewrite_rule('^' . $transaction . '/invoice/?$', 'index.php?__salesloo_page=transaction/invoice', 'top');

        add_rewrite_rule('^' . $transaction . '/order/([^/]+)/?$', 'index.php?__salesloo_page=transaction/order/id&__order=$matches[1]', 'top');

        add_rewrite_rule('^' . $transaction . '/order/?$', 'index.php?__salesloo_page=transaction/order', 'top');

        add_rewrite_rule('^order/([^/]+)/?$', 'index.php?__salesloo_page=order&__order=$matches[1]', 'top');


        add_rewrite_rule('^checkout/([^/]+)/?$', 'index.php?__salesloo_page=checkout&__product=$matches[1]', 'top');
        add_rewrite_rule('^checkout$', 'index.php?__salesloo_page=checkout', 'top');

        add_rewrite_rule('^renew/([^/]+)/?$', 'index.php?__salesloo_page=renew&__order=$matches[1]', 'top');

        add_rewrite_rule('^payment/([^/]+)/?$', 'index.php?__salesloo_page=payment&__invoice=$matches[1]', 'top');

        add_rewrite_rule('^thanks/([^/]+)/?$', 'index.php?__salesloo_page=thanks&__invoice=$matches[1]', 'top');
        add_rewrite_rule('^thanks/?$', 'index.php?__salesloo_page=thanks', 'top');


        add_rewrite_rule('^aff/([^/]+)/([^/]+)/?$', 'index.php?__salesloo_page=aff&__username=$matches[1]&__product=$matches[2]', 'top');

        add_rewrite_rule('^aff/([^/]+)/?$', 'index.php?__salesloo_page=aff&__username=$matches[1]', 'top');
    }


    /**
     * handle salesloo page
     */
    public function handle_page()
    {
        $template = $this->component()->get_template();

        if ($template) {
            $template = salesloo_get_template($template);

            if (false != $template && file_exists($template)) {

                $target = $this->component()->get_target();

                salesloo_load_layout($target, $template);
                exit;
            }

            $message = __('Unable to load template', 'salesloo');
            wp_die($message);
        }
    }

    /**
     * handle action submit
     */
    public function handle_action()
    {
        global $___salesloo;

        $component = $this->component();

        $target = $component->get_target();

        if ($target == 'user' && !is_user_logged_in()) {
            wp_redirect(salesloo_url_login());
            exit;
        } else if ($target == 'guest' && is_user_logged_in()) {
            wp_redirect(salesloo_url_dashboard());
            exit;
        }

        $request = new Request();
        $component->process_action($request);
        do_action('salesloo/frontend/' . $component->get_id() . '/action', $request, $component);
    }

    /**
     * handle load page;
     */
    public function handle_load()
    {
        global $post;

        if (false === __is_salesloo_page()) return;

        if (!is_admin() && Plugin::instance()->license->status != 200) {
            wp_die('Missing salesloo license, Please contact admin');
        }

        $post = null;

        $component = $this->component();
        $component->load();
        do_action('salesloo/frontend/' . $component->get_id() . '/load', $component);

        $args = [
            'ip' => User_Info::get_ip(),
            'time' => strtotime('now'),
        ];

        $nonce = salesloo_encrypt(json_encode($args));

        setcookie('wp_salesloo', $nonce, 0, COOKIEPATH, COOKIE_DOMAIN, false, true);
    }

    /**
     * load and run frontend component
     */
    public function get_classes()
    {
        $classes = [
            'register'             => '\Salesloo\Frontend\Register',
            'login'                => '\Salesloo\Frontend\Login',
            'login/reset-password' => '\Salesloo\Frontend\Reset_Password',
            'dashboard'            => '\Salesloo\Frontend\Dashboard',
            'product'              => '\Salesloo\Frontend\Product',
            'profile'              => '\Salesloo\Frontend\Profile',
            'affiliate/product'    => '\Salesloo\Frontend\Affiliate_Product',
            'affiliate/product/id' => '\Salesloo\Frontend\Affiliate_Product_Id',
            'affiliate/statistics' => '\Salesloo\Frontend\Affiliate_Statistics',
            'affiliate/commission' => '\Salesloo\Frontend\Affiliate_Commission',
            'affiliate/withdrawal' => '\Salesloo\Frontend\Affiliate_Withdrawal',
            'aff'                  => '\Salesloo\Frontend\Aff',
            'checkout'             => '\Salesloo\Frontend\Checkout',
            'renew'                => '\Salesloo\Frontend\Renew',
            'payment'              => '\Salesloo\Frontend\Payment',
            'transaction/invoice'  => '\Salesloo\Frontend\Transaction_Invoice',
            'transaction/order'    => '\Salesloo\Frontend\Transaction_Order',
            'transaction/order/id' => '\Salesloo\Frontend\Transaction_Order_Id',
            'thanks'               => '\Salesloo\Frontend\Thanks',
            'order'                => '\Salesloo\Frontend\Order',
        ];

        $classes = apply_filters('salesloo/frontend/classes', $classes);

        $this->classes = $classes;
    }

    /**
     * run current frontend class
     */
    private function component($name = false)
    {
        $pagename = $name ? $name : __is_salesloo_page();

        if (false === $pagename || $pagename && !isset($this->classes[$pagename])) return $this;

        if (null != $this->class) return $this->class;

        $this->class = new $this->classes[$pagename];

        return $this->class;
    }

    /**
     * do magic
     */
    public function __call($name, $arguments)
    {
        return false;
    }

    /**
     * change lost password url;
     */
    public function handle_lost_password_url($url, $redirect)
    {
        return salesloo_url_login() . 'lostpassword/';
    }

    /**
     * handle password lost action
     */
    public  function do_password_lost()
    {
        global $wp;

        if ('POST' == $_SERVER['REQUEST_METHOD']) {

            if (isset($_POST['__nonce']) || isset($_POST['_wp_http_referer'])) {
                $request = new Request();
                $this->component('login/reset-password')->process_action($request);
            }
        }

        wp_redirect(salesloo_url_login() . 'lostpassword');
        exit;
    }

    /**
     * templating
     */
    public function templating()
    {
        if (in_array($this->component()->get_id(), $this->new_alpine_js_pages)) return;

        require salesloo_get_template('templating/modal.php');
        require salesloo_get_template('templating/alert.php');
        require salesloo_get_template('templating/confirm.php');
        //require salesloo_get_template('templating/loader.php');
    }

    /**
     * Initialize the frontend components
     *
     * @since    1.0.0
     */
    public function __construct()
    {

        $this->new_alpine_js_pages = [
            'checkout',
            'payment',
            'renew'
        ];

        add_filter('query_vars',  [$this, 'add_query_vars']);
        add_action('init',  [$this, 'add_endpoint']);

        $this->get_classes();

        add_action('salesloo/head', [$this, 'print_head'], 1);
        add_action('salesloo/head', [$this, 'print_scripts'], 1);
        add_action('salesloo/footer', [$this, 'templating'], 1);


        add_filter('lostpassword_url', [$this, 'handle_lost_password_url'], 2, 999);
        add_action('login_form_lostpassword', [$this, 'do_password_lost']);

        add_action('parse_request', [$this, 'handle_action']);
        add_action('wp', [$this, 'handle_load']);

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