<?php

namespace WPD_Platform\Factories;

use WPD_Platform\Services\LoginService;

/**
 * External host implementation for sites hosted outside the platform
 *
 * Handles external site connections, authentication, and server information
 * for sites that are not directly managed by the platform.
 *
 * @package WPD_Platform\Factories
 * @since 1.0.0
 */
class ExternalHost extends BaseHost {

	/**
	 * Constructor
	 *
	 * Sets up the external host type and initializes necessary hooks and settings
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		parent::__construct();
		$this->host_type = self::TYPE_2;
		$token           = $this->get_db_token();
		$this->set_token( $token );

		// Set up auto-login functionality
		add_action( 'init', [ LoginService::instance(), 'do_autologin' ], - 1 );
		add_action( 'template_redirect', [ LoginService::instance(), 'do_autologin' ], 12 );

		// Define WordPress directory path
		$path = preg_replace( '/\/wp-content.*$/', '', __DIR__ );
		if ( ! defined( 'PLATFORM_WORDPRESS_DIR' ) ) {
			define( 'PLATFORM_WORDPRESS_DIR', $path );
		}

		add_action( 'admin_notices', [ $this, 'admin_notices' ] );
	}

	/**
	 * Implement basic HTTP authentication
	 *
	 * @since 1.0.0
	 * @return array Array of valid credentials
	 */
	public function base_access() {
		$valid_passwords = [ 'container' => $this->get_token() ];
		$valid_users     = array_keys( $valid_passwords );

		$user = $_SERVER['PHP_AUTH_USER'];
		$pass = $_SERVER['PHP_AUTH_PW'];

		$validated = in_array( $user, $valid_users ) && $pass == $valid_passwords[ $user ];

		if ( ! $validated ) {
			header( 'WWW-Authenticate: Basic realm="My Realm"' );
			header( 'HTTP/1.0 401 Unauthorized' );
			die( 'Not authorized' );
		}

		return $valid_passwords;
	}

	/**
	 * Restrict access to the site using basic HTTP authentication
	 *
	 * @since 1.0.0
	 * @return array Array of valid credentials
	 */
	public function restrict_access() {
		$path = preg_replace( '/\/wp-content.*$/', '', __DIR__ );
		if ( ! defined( 'PLATFORM_WORDPRESS_DIR' ) ) {
			define( 'PLATFORM_WORDPRESS_DIR', $path );
		}

		$valid_passwords = [ 'container' => $this->get_token() ];
		$valid_users     = array_keys( $valid_passwords );

		$user = $_SERVER['PHP_AUTH_USER'];
		$pass = $_SERVER['PHP_AUTH_PW'];

		$validated = in_array( $user, $valid_users ) && $pass == $valid_passwords[ $user ];

		if ( ! $validated ) {
			header( 'WWW-Authenticate: Basic realm="My Realm"' );
			header( 'HTTP/1.0 401 Unauthorized' );
			die( 'Not authorized' );
		}

		return $valid_passwords;
	}

	/**
	 * Check if the site is connected to the platform
	 *
	 * @since 1.0.0
	 * @return bool Whether the site is connected
	 */
	public function is_connected() {
		return get_option( 'wpd_connection_id' );
	}

	/**
	 * Get the external host service
	 *
	 * @since 1.0.0
	 * @return mixed The host service instance
	 */
	public function get_external_host()
	{
		return \WPD_Platform\Utils\HostResolver::get_host_service();
	}

	/**
	 * Get the server IP address
	 *
	 * @since 1.0.0
	 * @return string|bool The server IP address or false if not available
	 */
	public static function get_server_ip() {
		return isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : false;
	}

	/**
	 * Get the server software type
	 *
	 * @since 1.0.0
	 * @return string|bool The server software or false if not set
	 */
	public static function get_server_software() {
		return isset($_SERVER['SERVER_SOFTWARE']) ? $_SERVER['SERVER_SOFTWARE'] : false;
	}

	/**
	 * Check if CloudFlare is being used
	 *
	 * @since 1.0.0
	 * @return bool True if CloudFlare is used, false otherwise
	 */
	public static function is_using_cloudflare() {
		return isset($_SERVER['HTTP_CF_RAY']) || isset($_SERVER['HTTP_CDN_LOOP']);
	}

	/**
	 * Get the maximum execution time for PHP
	 *
	 * @since 1.0.0
	 * @return int The maximum execution time in seconds
	 */
	public static function get_max_execution_time() {
		return ini_get('max_execution_time');
	}

	/**
	 * Get the server memory limit for PHP
	 *
	 * @since 1.0.0
	 * @return string The memory limit value
	 */
	public static function get_server_memory_limit() {
		return ini_get('memory_limit');
	}

    /**
     * Gets the MySQL version.
     *
     * @return string
     */
    public static function get_mysql_version() {
        global $wpdb;
        return $wpdb->get_var('SELECT VERSION() AS version');
    }

    /**
     * Gets the MySQL version.
     *
     * @return string
     */
    public static function get_wp_memory_limit() {
        return WP_MEMORY_LIMIT;
    }

 	public function get_host_details() {
        $hostInfo = [
            'external_host' => $this->get_external_host(),
            'server_software' => $this->get_server_software(),
            'using_cloudflare' => $this->is_using_cloudflare(),
            'server_ip' => $this->get_server_ip(),
            'max_execution_time' => $this->get_max_execution_time(),
            'server_memory_limit' => $this->get_server_memory_limit(),
            'wp_memory_limit' => $this->get_wp_memory_limit(),
            'mysql_version' => $this->get_mysql_version()
        ];

        return $hostInfo;
    }


	/**
	 * Save site hash and partner hash in DB.
	 *
	 * @param string $site_id The container hash from CHQ.
	 * @param string $partner_hash Optional partner hash from CHQ response.
	 *
	 * @return void
	 */
	public function setup_connection( $site_id, $partner_hash = '' ) {
		update_option( 'wpd_connection_id', $site_id );

		$hash = $partner_hash ?: $this->get_partner_hash();
		if ( $hash ) {
			update_option( 'wpd_connection_partner_hash', $hash );
		}
	}

	/**
	 * Remove the site connection
	 *
	 * @since 1.0.0
	 * @return bool Whether the connection was removed successfully
	 */
	public function remove_connection() {
		delete_option( 'wpd_connection_id' );
		delete_option( self::TOKEN_OPTION );

		return true;
	}

	/**
	 * Get the partner hash
	 *
	 * @since 1.0.0
	 * @return string The partner hash
	 */
	public function get_partner_hash() {
		$partner_hash = '';

		if ( defined( 'WPD_PARTNER_ID' ) && ! empty( WPD_PARTNER_ID ) && strpos( WPD_PARTNER_ID, '[[' ) === false ) {
			update_option( 'wpd_connection_partner_hash', WPD_PARTNER_ID );
			return WPD_PARTNER_ID;
		}

		return get_option( 'wpd_connection_partner_hash', $partner_hash );
	}

	/**
	 * Connect site to HQ
	 *
	 * @return bool
	 */
	public function register_site() {
		if ( $this->is_connected() ) {
			return false;
		}

		$current_user = wp_get_current_user();

		if ( $current_user === null ) {
			return false;
		}

		$api_host = defined( 'WPD_WORKER_API_URL' ) ? WPD_WORKER_API_URL : self::API_URL;
		$response = wp_remote_post(
			$api_host . 'external-sites/connect',
			[
				'headers'   => array(
					'Authorization' => $this->get_token(),
				),
				'body'      => [
					'partner_hash' => $this->get_partner_hash(),
					'name'         => get_bloginfo( 'name' ),
					'description'  => get_bloginfo( 'description' ),
					'uri'          => site_url(),
					'username'     => $current_user->user_login,
					'email'        => $current_user->user_email,
					'wp_version'   => get_bloginfo( 'version' ),
					'php_version'  => phpversion(),
				],
				'timeout'   => 30,
				'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
			]
		);

		// Check for errors.
		if ( is_wp_error( $response ) ) {
			return false;
		}

		// Get the response data.
		$response_data = wp_remote_retrieve_body( $response );

		if ( empty( $response_data ) ) {
			return false;
		}

		$response_data = json_decode( $response_data );

		if ( ! is_object( $response_data ) ) {
			return false;
		}

		$partner_hash = isset( $response_data->partner_hash ) ? $response_data->partner_hash : '';
		$this->setup_connection( $response_data->id, $partner_hash );
		set_transient( 'wpd_connection_status', 'success', 10 );

		do_action( 'wpd_platform/after/register_site' );

		return $response_data->id;
	}

	/**
	 * Display connection messages in admin.
	 *
	 * @return void
	 */
	public function admin_notices() {
		$transient = get_transient( 'wpd_connection_status' );

		if ( $transient === 'success' && $this->is_connected() ) {
			?>
			<div class="notice notice-success is-dismissible">
				<p><?php _e( 'Your site has been connected to site management platform!', 'platform' ); ?></p>
			</div>
			<?php
		} elseif ( $transient === 'failure' ) {
			?>
			<div class="notice notice-error is-dismissible">
				<p><?php _e( 'There was an error connecting your site to management platform. Please contact support!', 'platform' ); ?></p>
			</div>
			<?php
		}
	}
}
