<?php

namespace orderflow\Facebook;

use Jaybizzle\CrawlerDetect\CrawlerDetect;
use orderflow\Settings;

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

/**
 * OrderFlow Facebook Pixel Core class
 */
final class PYS extends Settings {
	
	private static $_instance;

	/** @var $eventsManager EventsManager */
	private $eventsManager;

    /** @var $registeredPixels array Registered pixels */
    private $registeredPixels = array();

    private $pixels_loaded = false;
    private $crawlerDetect;
    private $externalId;
    /**
     * @var Logger
     */
    private $logger;

    public static function instance() {

		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		
		return self::$_instance;
		
	}
	
    public function __construct() {
		
	    // initialize settings
	    parent::__construct( 'core' );
    
        // Priority 9 used to keep things same as on PRO version
        add_action( 'wp', array( $this, 'controllSessionStart'), 10);
        add_action( 'init', array( $this, 'set_pbid'), 8);
        add_action( 'init', array( $this, 'init' ), 9 );

        // run Events Manager
        add_action( 'template_redirect', array( $this, 'managePixels' ), 1);
        // track user login event
        add_action('wp_login', [$this,'userLogin'], 10, 2);
        // track user registrations
        add_action( 'user_register', array( $this, 'userRegisterHandler' ) );

        add_action( 'wp_ajax_pys_get_pbid', array( $this, 'get_pbid_ajax' ) );
        add_action( 'wp_ajax_nopriv_pys_get_pbid', array( $this, 'get_pbid_ajax' ) );

        if ( class_exists( 'Jaybizzle\CrawlerDetect\CrawlerDetect' ) ) {
            $this->crawlerDetect = new CrawlerDetect();
        } else {
            // Fallback if CrawlerDetect not available
            $this->crawlerDetect = null;
        }
        
        $this->logger = new Logger();
    }

    public function init() {
	    // initialize options
	    $this->locateOptions(
		    ADS_PLUGIN_PATH . '/includes/options_fields.json',
		    ADS_PLUGIN_PATH . '/includes/options_defaults.json'
	    );
	    
	    // register pixels
	    do_action( 'pys_register_pixels', $this );

        // maybe disable Facebook for WooCommerce pixel output
	    if ( function_exists('isWooCommerceActive') && isWooCommerceActive()
	         && array_key_exists( 'orderflow_facebook', $this->registeredPixels ) && Facebook()->configured() ) {
		    add_filter( 'facebook_for_woocommerce_integration_pixel_enabled', '__return_false' );
	    }

        if(Facebook()->getOption('test_api_event_code_expiration_at'))
        {
            foreach (Facebook()->getOption('test_api_event_code_expiration_at') as $key => $test_code_expiration_at)
            {
                if(time() >= $test_code_expiration_at)
                {
                    Facebook()->updateOptions(array("test_api_event_code" => array()));
                    Facebook()->updateOptions(array("test_api_event_code_expiration_at" => array()));
                }
            }
        }
    }

    public function get_pbid_ajax(){
        if(defined('DOING_AJAX') && DOING_AJAX){
            $isTrackExternalId = EventsManager::isTrackExternalId();
            if ($isTrackExternalId && !empty($this->externalId)) {
                $transient = get_transient('externalId-'.PYS()->get_user_ip());
                wp_send_json_success( array('pbid'=> $this->externalId, 'transient' => !empty($transient) ? $transient : false ));
            }
        }
    }

    function controllSessionStart(){
        if($this->getOption('session_disable')) return;

        // Checking if the directory exists and is writable
        if (!is_admin() && PHP_SAPI !== 'cli' && session_status() != PHP_SESSION_DISABLED) {
            if (!headers_sent() && session_status() === PHP_SESSION_NONE) {
                if (!session_start()) return;
            }

            if (session_status() !== PHP_SESSION_ACTIVE) return;

            if (empty($_SESSION['TrafficSource'])) {
                $_SESSION['TrafficSource'] = getTrafficSource();
            }
            if (empty($_SESSION['LandingPage'])) {
                $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://';
                $currentUrl = $protocol . ($_SERVER['HTTP_HOST'] ?? parse_url(get_site_url(), PHP_URL_HOST)) . ($_SERVER['REQUEST_URI'] ?? '');
                $landing = explode('?', $currentUrl)[0];
                $_SESSION['LandingPage'] = $landing;
            }
            if (empty($_SESSION['TrafficUtms'])) {
                $_SESSION['TrafficUtms'] = getUtms();
            }
        }
    }


    /**
     * Hook
     * @param String $user_login
     * @param \WP_User $user
     */
    function userLogin($user_login, $user) {
        update_user_meta($user->ID,'of_pys_just_login',true);

		if ( !apply_filters( 'of_pys_disable_advanced_form_data_cookie', false ) && !apply_filters( 'of_pys_disable_advance_data_cookie', false ) ) {
			$user_persistence_data = get_persistence_user_data( $user->user_email, $user->first_name, $user->last_name, '' );
			$userData = array(
				'first_name' => $user_persistence_data[ 'fn' ],
				'last_name'  => $user_persistence_data[ 'ln' ],
				'email'      => $user_persistence_data[ 'em' ],
				'phone'      => $user_persistence_data[ 'tel' ]
			);
			setcookie( "of_pys_advanced_form_data", json_encode( $userData ), 2147483647, '/' );
		}
    }

    public function userRegisterHandler( $user_id ) {
        if ( $this->getOption( 'woo_complete_registration_enabled' ) ) {
            update_user_meta( $user_id, 'of_pys_complete_registration', true );
        }
    }

	/**
	 * Register pixel
	 *
	 * @param Pixel|Settings $pixel
	 */
    public function registerPixel( &$pixel ) {
        // Only register Facebook pixel
        if ( $pixel->getSlug() === 'orderflow_facebook' ) {
            $this->registeredPixels[ $pixel->getSlug() ] = $pixel;
        }
    }

	/**
	 * Return array of registered pixels
	 *
	 * @return array
	 */
	public function getRegisteredPixels() {
		return $this->registeredPixels;
	}


	/**
	 * Front-end entry point
	 */
    public function managePixels() {

        if ( $this->pixels_loaded ) {
            return;
        }
        $this->pixels_loaded = true;

        if (defined('DOING_AJAX') && DOING_AJAX) {
            return;
        }

        // disable Events Manager on Customizer and preview mode
        if (is_admin() || is_customize_preview() || is_preview()) {
            return;
        }

        // disable Events Manager on Elementor editor
        if (did_action('elementor/preview/init')
            || did_action('elementor/editor/init')
            || (isset( $_GET['action'] ) && $_GET['action'] == 'piotnetforms')
        ) {
            return;
        }

        // disable Events Manager on Divi Builder
        if (function_exists('et_core_is_fb_enabled') && et_core_is_fb_enabled()) {
            return;
        }

    	// output debug info
        if(!$this->getOption( 'hide_version_plugin_in_console')) {
            add_action('wp_head', function () {
                echo "<script type='application/javascript'  id='orderflow-fb-version-script'>console.log('OrderFlow Facebook Pixel version 1.0.0');</script>\r\n";
            }, 1);
        }
	    
        if ( isDisabledForCurrentRole() ) {
	    	return;
	    }
	    
        // setup events
        $this->eventsManager = new EventsManager();
        
        // Initialize Custom Events Manager
        \orderflow\Facebook\Custom_Events_Manager::instance();
	    
	    // at least one pixel should be configured
	    $facebook_configured = Facebook()->configured();
	    
	    if ( ! $facebook_configured ) {
            if(!$this->getOption( 'hide_version_plugin_in_console')) {
                add_action('wp_head', function () {
                    echo "<script type='application/javascript' id='orderflow-fb-config-warning-script'>console.warn('OrderFlow Facebook Pixel: no pixel configured.');</script>\r\n";
                });
            }
	    	return;
	    }
    }

    public function getEventsManager() {
        return $this->eventsManager;
    }

    function is_user_agent_bot(){
        if (!$this->getOption('block_robot_enabled')) {
            return false;
        }
        if (!empty($_SERVER['HTTP_USER_AGENT'])) {
            $userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
            $options = array(
                'YandexBot', 'Googlebot', 'bingbot', 'Baiduspider', 'facebookexternalhit'
            );
            foreach($options as $row) {
                if (stripos($userAgent, strtolower($row)) !== false) {
                    return true;
                }
            }
        }
        if ( $this->crawlerDetect ) {
            return $this->crawlerDetect->isCrawler();
        }
        return false;
    }

    public function isCachePreload() {
        return false;
    }

    function get_pbid(){
        return $this->externalId;
    }
    
    function set_pbid() {
        $pbidCookieName = 'pbid';
        $isTrackExternalId = EventsManager::isTrackExternalId();
        $user = wp_get_current_user();

        if ($user && $isTrackExternalId) {
            $userExternalId = $user->get('external_id');
            if (!empty($userExternalId)) {
                $this->externalId = $userExternalId;
                return;
            }
        }

        if ($isTrackExternalId) {
            if (!empty($_COOKIE[$pbidCookieName])) {
                $this->externalId = $_COOKIE[$pbidCookieName];
            } elseif ( $this->getOption('external_id_use_transient') && get_transient('externalId-' . $this->get_user_ip())) {
                $this->externalId = get_transient('externalId-' . $this->get_user_ip());
            }
            else {
                $uniqueId = bin2hex(random_bytes(16));
                $encryptedUniqueId = hash('sha256', $uniqueId);
                $this->externalId = $encryptedUniqueId;
                if($this->getOption('external_id_use_transient')){
                    set_transient('externalId-' . $this->get_user_ip(), $this->externalId, 60 * 10);
                }
            }
        }
    }
    
    function get_user_ip() {
        $ip = $_SERVER['REMOTE_ADDR'] ?? null;

        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $forwarded_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $ip = trim($forwarded_ips[0]);
        } elseif (!empty($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        }

        return filter_var($ip, FILTER_VALIDATE_IP) ?: '0.0.0.0';
    }

    public function getLog() {
        return $this->logger;
    }

    function woo_is_order_received_page() {
        if(function_exists('is_order_received_page') && is_order_received_page()) return true;
        global $post;
        $ids = PYS()->getOption("woo_checkout_page_ids");
        if(!empty($ids)) {
            if($post && in_array($post->ID,$ids)) {
                return true;
            }
        }
        if (did_action( 'elementor/loaded' )) {
            if ($post) {
                $elementor_page_id = get_option('elementor_woocommerce_purchase_summary_page_id');
                if ($elementor_page_id == $post->ID) return true;
            }
        }

        if(function_exists('is_wc_endpoint_url') && is_wc_endpoint_url( 'order-received')){
            return true;
        }
        return false;
    }
}

/**
 * @return PYS
 */
function PYS() {
    return \orderflow\Facebook\PYS::instance();
}

