<?php
/**
 * Global Rest Functions
 *
 * @package Nisje
 */

defined( 'ABSPATH' ) || die( 'Shame on you' );

/**
 * Return the REST namespace for Nisje.
 *
 * @return string Namespace.
 */
function nisje_get_rest_namespace() {
	return 'dekode-intranet/v1';
}

/**
 * Helper for overriding rest permission checks. This can potentially open up Nisje. Use with care!
 *
 * @param string          $endpoint Endpoint to validate against.
 * @param string          $route    Endpoint route.
 * @param WP_REST_Request $request  Full data about the request.
 *
 * @return bool True or false
 */
function nisje_override_rest_permission_check( $endpoint = '', $route = '', $request ) {
	return apply_filters( 'nisje_override_rest_permission_check', false, $endpoint, $route, $request );
}

/**
 * Helper for checking if user needs to be logged in to view rest endpoints.
 *
 * @param string $endpoint Endpoint to validate against.
 * @param string $route    Endpoint route.
 *
 * @return bool|WP_Error True if user is logged in else WP_Error
 */
function nisje_validate_rest_authentication( $endpoint = '', $route = '' ) {
	$authenticate = apply_filters( 'nisje_validate_rest_authentication', true, $endpoint, $route );

	if ( $authenticate && ! is_user_logged_in() ) {
		return new \WP_Error( 'nisje_rest_user_not_logged_in', esc_html__( 'Only registered and logged in members can use this API.', 'nisje' ), [
			'status' => rest_authorization_required_code(),
		] );
	}

	return true;
}

/**
 * Helper for validating against current user.
 *
 * @param int $user_id User ID.
 * @return bool|WP_Error True if user is validated.
 */
function nisje_validate_current_user( $user_id ) {
	if ( bp_loggedin_user_id() !== $user_id ) {
		return new \WP_Error( 'nisje_rest_not_current_user', esc_html__( 'You are not allowed to perform actions as this user.', 'nisje' ), [
			'status' => rest_authorization_required_code(),
		] );
	}

	return true;
}

/**
 * Helper for checking if a user is excluded.
 *
 * @param int $user_id User ID to validate against.
 * @return bool|WP_Error True if user is logged in else WP_Error
 */
function nisje_validate_rest_excluded( $user_id ) {
	if ( nisje_is_excluded_member( $user_id ) ) {
		return new \WP_Error( 'nisje_rest_excluded', esc_html__( 'Excluded members cannot access this endpoint.', 'nisje' ), [
			'status' => 400,
		] );
	}

	return true;
}

/**
 * Convert the input date to RFC3339 format.
 *
 * @param string      $date_gmt Date GMT.
 * @param string|null $date     Optional. Date object.
 *
 * @return string|null ISO8601/RFC3339 formatted datetime.
 */
function nisje_prepare_date_response( $date_gmt, $date = null ) {
	if ( isset( $date ) ) {
		return mysql_to_rfc3339( $date );
	}

	if ( '0000-00-00 00:00:00' === $date_gmt ) {
		return null;
	}

	return mysql_to_rfc3339( $date_gmt );
}

/**
 * Helper for getting group based on group id. Sets the group as current group in the global $bp object.
 *
 * @param int  $group_id  The id of the group.
 * @param bool $set_group Set as current group in BP.

 * @return \WP_Error|\BP_Groups_Group
 */
function nisje_get_group( $group_id = 0, $set_group = false ) {
	$group_id = (int) $group_id;
	$group    = groups_get_group( $group_id );
	if ( empty( $group ) || empty( $group->id ) ) {
		return new \WP_Error( 'nisje_rest_group_not_found', esc_html__( 'Group not found.', 'nisje' ), [
			'status' => 404,
		] );
	}

	if ( $set_group ) {
		nisje_set_group( $group );
	}

	return $group;
}

/**
 * Helper for setting group in the global BP scope. Some of the underlaying functionality rely on it.
 *
 * @param object $group Group Object.
 * @return void
 */
function nisje_set_group( $group ) {
	global $bp;

	$bp->groups->current_group = $group;
	$bp->current_component     = 'groups';

	// Using "item" not "group" for generic support in other components.
	if ( bp_current_user_can( 'bp_moderate' ) ) {
		bp_update_is_item_admin( true, 'groups' );
	} else {
		bp_update_is_item_admin( groups_is_user_admin( bp_loggedin_user_id(), $group->id ), 'groups' );
	}

	// If the user is not an admin, check if they are a moderator.
	if ( ! bp_is_item_admin() ) {
		bp_update_is_item_mod( groups_is_user_mod( bp_loggedin_user_id(), $group->id ), 'groups' );
	}

	// Check if current user is member of the group.
	if ( ( is_user_logged_in() && groups_is_user_member( bp_loggedin_user_id(), $group->id ) ) ) {
		$bp->groups->current_group->is_user_member = true;
	} else {
		$bp->groups->current_group->is_user_member = false;
	}

	// Should this group be visible to the logged in user?
	if ( 'public' === $group->status || $bp->groups->current_group->is_user_member ) {
		$bp->groups->current_group->is_visible = true;
	} else {
		$bp->groups->current_group->is_visible = false;
	}
}

/**
 * Populate image data into rest API based on attchment id.
 *
 * @param int $image_id Image.
 * @return array Populated Image array
 */
function nisje_populate_image_data( $image_id ) {
	if ( ! is_numeric( $image_id ) ) {
		return false;
	}

	$sizes = [
		'thumbnail',
		'medium',
		'medium-large',
		'large',
	];

	$size_array = [];

	foreach ( $sizes as $size ) {
		$src = wp_get_attachment_image_src( $image_id, $size );
		if ( isset( $src[0], $src[1], $src[2] ) ) {
			$size_array[ $size ]             = $src[0];
			$size_array[ $size . '-width' ]  = $src[1];
			$size_array[ $size . '-height' ] = $src[2];
		}
	}

	$url = wp_get_attachment_image_src( $image_id, 'full' );

	$image_arr = [
		'sizes' => $size_array,
		'url'   => isset( $url[0] ) ? esc_url( $url[0] ) : '',
		'id'    => $image_id,
		'title' => get_the_title( $image_id ),
	];

	return apply_filters( 'nisje_filter_image_data', $image_arr );
}

/**
 * Build a hierarchy list of taxnomies.
 *
 * @param WP_Term $category     Category to base the hierarchy off.
 * @param string  $tax_name     Taxonomy name.
 * @param boolean $add_category Whether to add the category as first item.
 *
 * @return Array
 */
function nisje_taxonomy_hierarchy( $category, $tax_name = '', $add_category = false ) {
	$hierarchy = [];

	if ( is_numeric( $category ) ) {
		$category = get_term_by( 'id', $category, $tax_name );
	}

	if ( $category instanceof \WP_Term ) {
		if ( $add_category ) {
			$hierarchy[] = $category;
		}

		$current_cat = $category;

		while ( $current_cat->parent ) {
			$current_cat = get_term_by( 'id', $current_cat->parent, $tax_name );
			$hierarchy[] = $current_cat;
		}
	}

	return array_reverse( $hierarchy );
}

/**
 * Check if user is excluded.
 *
 * @param int $member_id Member id.
 * @return bool If user is excluded or not.
 */
function nisje_is_excluded_member( $member_id ) {
	$excludes = (array) nisje_get_setting( 'exclude_members', 'general' );
	if ( in_array( $member_id, $excludes, true ) ) {
		return true;
	} else {
		return false;
	}
}

/**
 * Filter Editor values.
 *
 * @param string $value Value from editor.
 * @return string Filteret value.
 */
function nisje_filter_editor_value( $value ) {
	$value = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $value );
	$value = convert_smilies( $value );
	$value = convert_chars( $value );
	$value = make_clickable( $value );
	$value = stripslashes_deep( $value );

	return $value;
}

/**
 * Filter Editor values.
 *
 * @param string $value Value from editor.
 * @return string Filteret value.
 */
function nisje_filter_string_value( $value ) {
	$value = preg_replace( '@<(script|style)[^>]*?>.*?</\\1>@si', '', $value );
	$value = convert_smilies( $value );
	$value = convert_chars( $value );
	$value = stripslashes_deep( $value );

	return $value;
}

/**
 * Build array with display name from array with user ids.
 *
 * @param array $users User IDs.
 * @return array Array with display name.
 */
function nisje_get_user_names( $users ) {
	$users_data = [];

	foreach ( $users as $user ) {
		$users_data[] = [
			'name' => bp_core_get_user_displayname( $user ),
			'id'   => $user,
		];
	}

	return $users_data;
}
