<?php
/**
 * GRoups
 *
 * @package Nisje
 */

declare( strict_types = 1 );
namespace Nisje\Groups;

defined( 'ABSPATH' ) || die( 'This is Nisje!' );

/**
 * Filters
 */
add_action( 'rest_api_init', __NAMESPACE__ . '\\register_api_init' );
add_filter( 'bp_rest_group_schema', __NAMESPACE__ . '\\group_schema' );
add_action( 'bp_actions', __NAMESPACE__ . '\\groups_action_create_group', 9 );
add_filter( 'nisje_notification_enrich_data', __NAMESPACE__ . '\\enrich_notification_data', 10, 3 );

/**
 * Extend with custom rest fields.
 *
 * @return void
 */
function register_api_init() {
	bp_rest_register_field( 'groups', 'total_member_count', [
		'get_callback' => function( $group ) {
			return (int) groups_get_groupmeta( $group['id'], 'total_member_count', true );
		},
		'schema'       => [
			'context'     => [ 'view', 'edit' ],
			'description' => esc_html__( 'Count of all Group members.', 'nisje' ),
			'readonly'    => true,
			'type'        => 'integer',
		],
	] );

	bp_rest_register_field( 'groups', 'last_activity', [
		'get_callback' => function( $group ) {
			return bp_rest_prepare_date_response( groups_get_groupmeta( $group['id'], 'last_activity' ) );
		},
		'schema'       => [
			'context'     => [ 'view', 'edit' ],
			'description' => esc_html__( 'The date the Group was last active, in the site\'s timezone', 'nisje' ),
			'type'        => 'string',
			'readonly'    => true,
			'format'      => 'date-time',
		],
	] );

	bp_rest_register_field( 'groups', 'group_types', [
		'get_callback' => function( $group ) {
			return bp_groups_get_group_type( $group['id'] );
		},
		'schema'       => [
			'context'           => [ 'view', 'edit', 'member' ],
			'description'       => esc_html__( 'Group Types.', 'nisje' ),
			'readonly'          => true,
			'type'              => 'array',
			'items'             => [
				'type' => 'string',
			],
			'sanitize_callback' => function( $value ) {
				if ( ! empty( $value ) ) {
					$types = explode( ',', $value );

					$registered_types = bp_groups_get_group_types();

					$valid_types = array_intersect( $types, $registered_types );

					if ( ! empty( $valid_types ) ) {
						return $valid_types;
					} else {
						return null;
					}
				}

				return $value;
			},
			'validate_callback' => function( $value, $request, $param ) {
				if ( ! empty( $value ) ) {
					$types = explode( ',', $value );

					$registered_types = bp_groups_get_group_types();
					foreach ( $types as $type ) {
						if ( ! in_array( $type, $registered_types, true ) ) {
							// translators: 1: user provied group type 2: List of registered group types.
							return new \WP_Error( 'nisje_rest_group_invalid_group_type', sprintf( esc_html__( 'The group type you provided, %1$s, is not one of %2$s.', 'nisje' ), $type, implode( ', ', $registered_types ) ) );
						}
					}
				}
				return true;
			},
		],
	] );
}

/**
 * Filters the group schema.
 *
 * @param array $schema The endpoint schema.
 */
function group_schema( array $schema ) : array {
	if ( isset( $schema['properties']['id'] ) ) {
		$schema['properties']['id']['context'][] = 'listing';
	}

	if ( isset( $schema['properties']['name'] ) ) {
		$schema['properties']['name']['context'][] = 'listing';
	}

	return $schema;
}

/**
 * Redirect to react create screen.
 */
function groups_action_create_group() {
	if ( ! bp_is_groups_component() || ! bp_is_current_action( 'create' ) ) {
		return;
	}

	bp_core_redirect( trailingslashit( bp_get_groups_directory_permalink() ) . 'new' );
}

/**
 * Populate Notifications
 *
 * @param array  $args         Arguments.
 * @param string $action       Action.
 * @param array  $notification Arguments.
 */
function enrich_notification_data( array $args, string $action, array $notification ) : array {
	$group_actions = [
		'group_invite',
		'member_promoted_to_admin',
		'member_promoted_to_mod',
		'membership_request_accepted',
		'membership_request_rejected',
		'new_group_post',
		'new_membership_request',
	];

	if ( in_array( $action, $group_actions, true ) ) {
		$group = nisje_get_group( $notification['item_id'] );

		if ( ! is_wp_error( $group ) ) {
			$args['avatar']  = $notification['item_id'];
			$args['context'] = 'groups';
			$args['item_id'] = $group->name;

			if ( 'new_membership_request' === $action ) {
				$args['secondary_item_id'] = bp_core_get_user_displayname( $notification['secondary_item_id'] );
				$args['href']              = '/groups/' . $notification['item_id'] . '/admin/membership-requests/';
				$args['message']           = [
					'raw'      => '%1$s requested membership to the group %2$s',
					// translators: %1$s name of the user requesting membership, %2$s group name.
					'rendered' => sprintf( esc_html__( '%1$s requested membership to the group %2$s', 'nisje' ),
						'<strong>' . $args['secondary_item_id'] . '</strong>',
						'<strong>' . $group->name . '</strong>'
					),
				];
			} elseif ( 'membership_request_accepted' === $action ) {
				$args['href']    = '/groups/' . $notification['item_id'] . '/';
				$args['message'] = [
					'raw'      => 'Your membership request for %s was accepted',
					// translators: %s group name.
					'rendered' => sprintf( esc_html__( 'Your membership request for %s was accepted', 'nisje' ),
						'<strong>' . $group->name . '</strong>'
					),
				];
			} elseif ( 'membership_request_rejected' === $action ) {
				$args['href']    = '/groups/' . $notification['item_id'] . '/';
				$args['message'] = [
					'raw'      => 'Your membership request for %s was rejected',
					// translators: %s group name.
					'rendered' => sprintf( esc_html__( 'Your membership request for %s was rejected', 'nisje' ),
						'<strong>' . $group->name . '</strong>'
					),
				];
			} elseif ( 'group_invite' === $action ) {
				$args['href']    = '/members/' . $notification['user_id'] . '/groups/invites/';
				$args['message'] = [
					'raw'      => 'You have an invitation to the group: %1$s',
					// translators: %1$s name of the group.
					'rendered' => sprintf( esc_html__( 'You have an invitation to the group: %1$s', 'nisje' ),
						'<strong>' . $group->name . '</strong>'
					),
				];
			} elseif ( 'member_promoted_to_admin' === $action ) {
				$args['href']    = '/groups/' . $notification['item_id'] . '/';
				$args['message'] = [
					'raw'      => 'You are promoted to admin in the group %1$s',
					// translators: %1$s group name.
					'rendered' => sprintf( esc_html__( 'You are promoted to admin in the group %1$s', 'nisje' ),
						'<strong>' . $group->name . '</strong>'
					),
				];
			} elseif ( 'member_promoted_to_mod' === $action ) {
				$args['href']    = '/groups/' . $notification['item_id'] . '/';
				$args['message'] = [
					'raw'      => 'You are promoted to moderator in the group %1$s',
					// translators: %1$s group name.
					'rendered' => sprintf( esc_html__( 'You are promoted to moderator in the group %1$s', 'nisje' ),
						'<strong>' . $group->name . '</strong>'
					),
				];
			} elseif ( 'new_group_post' === $action ) {
				$args['href']    = '/groups/' . $notification['item_id'] . '/';
				$args['message'] = [
					'raw'      => 'There is a new group post in the group %1$s',
					// translators: %1$s group name.
					'rendered' => sprintf( esc_html__( 'There is a new group post in the group %1$s', 'nisje' ),
						'<strong>' . $group->name . '</strong>'
					),
				];
			}
		}
	}

	return $args;
}
