<?php

namespace GemBoards\Hooks;

use GemBoards\Classes\PermissionResolver;
use GemBoards\Utils\Helper;
use WP_User;

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

class User {

	protected bool $has_avatar = false;

	public static function init() {
		$self = new self();

		add_filter( 'get_avatar_url', [ $self, 'replace_avatar_url' ], 10, 2 );
		add_filter( 'user_profile_picture_description', [ $self, 'replace_profile_picture_description' ], 10, 2 );
		add_filter( 'user_has_cap', [ $self, 'extend_user_capabilities' ], 10, 3);

		add_filter( 'map_meta_cap', [ $self, 'grant_delete_attachments_capability' ], 10, 4 );
	}

	/**
	 * Override the default avatar with user's custom one
	 */
	public function replace_avatar_url( $url, $id_or_email ) {
		$user = false;

		if ( is_numeric( $id_or_email ) ) {
			$user = get_user_by( 'id', (int) $id_or_email );
		} elseif ( is_object( $id_or_email ) && ! empty( $id_or_email->user_id ) ) {
			$user = get_user_by( 'id', (int) $id_or_email->user_id );
		} elseif ( is_string( $id_or_email ) ) {
			$user = get_user_by( 'email', $id_or_email );
		}

		if ( $user ) {
			$custom_avatar = get_user_meta( $user->ID, 'gemboards_avatar', true );
			if ( ! empty( $custom_avatar ) ) {
				$avatar_url = wp_get_attachment_image_url( absint( $custom_avatar ) );
				if ( ! empty( $avatar_url ) ) {
					$this->has_avatar = true;

					return $avatar_url;
				}
			}
		}

		return $url;
	}

	public function replace_profile_picture_description( string $description, WP_User $user ): string {
		if ( $this->has_avatar ) {
			return sprintf(
			/* translators: %s: Gemboards settings URL. */
				__( '<a href="%s">You can change your profile picture on Gemboards settings</a>.', 'gemboards' ),
				Helper::get_settings_url()
			);
		}

		return $description;
	}

	public function extend_user_capabilities( $all_caps, $caps, $args ) {
		global $gemboards_settings;
		$permissions = array_keys( (array) $gemboards_settings->permissions);

		foreach ( $caps as $cap ) {
			if ( 'manage_gemboards_labels' === $cap ) {
				$user_permissions = array_unique(
					array_merge(
						...array_map( fn ( $role ) => array_keys(
							array_filter( (array) $gemboards_settings->permissions, fn( $permission ) => $permission->{$role->get_role()} )
						), Helper::get_user_roles( get_current_user_id() ) )
					)
				);
				$all_caps[ $cap ] = in_array( 'manage_tasks', $user_permissions, true );
			} elseif ( in_array($cap, $permissions, true) && isset( $args[2]) ) {
				if ( true === ( $all_caps['manage_gemboards'] ?? false ) ) {
					$all_caps[ $cap ] = true;
				} elseif ( PermissionResolver::can( $cap, $args[2] ) ) {
					$all_caps[ $cap ] = true;
				}
			}
		}

		if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
			$action = sanitize_text_field(wp_unslash($_REQUEST['action'] ?? ''));
			if ( ( 'upload-attachment' === $action && isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'])), 'media-form' ) || ( 'query-attachments' === $action ) ) ) {
				$all_caps['upload_files']       = true;
				$all_caps['delete_attachments'] = true;
			} elseif ( 'delete-post' === $action ) {
				$post_id = isset( $_REQUEST['id'] ) ? absint($_REQUEST['id']) : 0;
				if (
					$post_id &&
					isset( $_REQUEST['_wpnonce'] ) &&
					wp_verify_nonce( sanitize_text_field(wp_unslash($_REQUEST['_wpnonce'])), "delete-post_$post_id" )
				) {
					$all_caps['delete_attachments'] = true;
				}
			}
		}

		return $all_caps;
	}

	public function grant_delete_attachments_capability( $caps, $cap, $user_id, $args ) {
		if ( 'delete_post' !== $cap ) {
			return $caps;
		}

		$post_id = $args[0] ?? 0;
		if ( ! $post_id ) {
			return $caps;
		}

		$post = get_post( $post_id );
		if ( ! $post || 'attachment' !== $post->post_type || (int) $post->post_author !== (int) $user_id ) {
			return $caps;
		}

		return [ 'delete_attachments' ];
	}
}
