<?php

namespace RtmBusiness\PostSync;

use WordpressModels\Assets;
use WordpressModels\Traits\SingletonTrait;

class PermissionController
{
    use SingletonTrait;

    private Assets $assets;

    /**
     * @param Assets $assets The assets configuration to use for enqueuing
     */
    public function __construct(Assets $assets)
    {
        $this->assets = $assets;

        //User profile hooks
        add_action('edit_user_profile', [$this, 'showCustomUserProfileOptions']);
        add_action('show_user_profile', [$this, 'showCustomUserProfileOptions']);
        add_action('edit_user_profile_update', [$this, 'save_custom_user_profile_fields']);
        add_action('personal_options_update', [$this, 'save_custom_user_profile_fields']);

        //Enque tomselect
        add_action('admin_enqueue_scripts', [$this, 'load_custom_wp_admin_style']);

        //Enforce permissions
        add_action('before_delete_post', [$this, 'beforePermDelete']);
        add_action('wp_trash_post', [$this, 'beforeMoveToTrash']);
        add_filter('pre_untrash_post', [$this, 'beforeRestorePost'], 10, 3);

        //Admin page notices
        add_action('admin_notices', [$this, 'display_admin_notice']);
    }

    /**
     * @param $untrash
     * @param $post
     * @param $previous_status
     * @return mixed|void
     */
    public function beforeRestorePost($untrash, $post, $previous_status)
    {
        //Check whether this post is either a parent or child of sync relation
        if (SyncController::instance()->isParentOrChild(get_current_blog_id(), $post->ID)) {
            if (!current_user_can('postsync_can_trashrestore')) {
                // Store the error message in a transient
                set_transient('my_admin_notice', "You don't have permission to restore posts from trash on this blog.", 45);
                // Redirect to the previous page
                wp_redirect($_SERVER['HTTP_REFERER']);
                exit;
            }
        }
        return $untrash;
    }

    /**
     * @param $post_id
     * @return void
     */
    public function beforeMoveToTrash($post_id)
    {
        //Check whether this post is either a parent or child of sync relation
        if (SyncController::instance()->isParentOrChild(get_current_blog_id(), $post_id)) {
            if (!current_user_can('postsync_can_trashrestore')) {
                set_transient('my_admin_notice', "You don't have permission to move synced posts to trash on this blog.", 45);
                wp_redirect($_SERVER['HTTP_REFERER']);
                exit;
            }
        }
    }

    /**
     * @param $postId
     * @return void
     */
    public function beforePermDelete($postId)
    {
        //Check whether this post is either a parent or child of sync relation
        if (SyncController::instance()->isParentOrChild(get_current_blog_id(), $postId)) {
            if (!current_user_can('postsync_can_permdelete')) {
                // Store the error message in a transient
                set_transient('my_admin_notice', "You don't have permission to permanently delete synced posts on this blog.", 45);
                wp_redirect($_SERVER['HTTP_REFERER']);
                exit;
            }
        }
    }


    /**
     * Displays the admin notice stored in the transient 'my_admin_notice'
     * @return void
     */
    public function display_admin_notice()
    {
        if ($notice = get_transient('my_admin_notice')) {
            delete_transient('my_admin_notice');

            echo '<div class="notice notice-error is-dismissible">';
            echo '<p>' . $notice . '</p>';
            echo '</div>';
        }
    }

    /**
     * Loads the custom js for tomselect
     * @param $hook
     * @return void
     */
    public function load_custom_wp_admin_style($hook)
    {
        // Load only on user edit page
        if ($hook != 'user-edit.php' && $hook != 'profile.php') {
            return;
        }

        $this->assets->enqueueCompiledScript('user-tomselect');
    }


    /**
     * Adds custom user profile options to manage permissions
     * @param $user
     * @return void
     */
    public function showCustomUserProfileOptions($user)
    {
        // Get all blogs/sites
        $blogs = get_sites();

        // Prepare data
        $preparedData = [];
        foreach ($blogs as $blog) {
            $blog_details = get_blog_details($blog->blog_id);
            switch_to_blog($blog->blog_id);

            $preparedData[] = [
                'blog_id' => $blog->blog_id,
                'blog_name' => $blog_details->blogname . ' (Blog ID:' . $blog->blog_id . ')',
                'can_publish' => $user->has_cap('postsync_can_publish'),
                'can_disconnect' => $user->has_cap('postsync_can_disconnect'),
                'can_trashrestore' => $user->has_cap('postsync_can_trashrestore'),
                'can_permdelete' => $user->has_cap('postsync_can_permdelete')
            ];

            restore_current_blog();
        }

        // Build template
        ?>
        <h3>Manage Sync Permissions</h3>
        <table class="form-table">
            <tr>
                <th><label for="postsync_manage_sync">Publish:</label></th>
                <th><label for="postsync_manage_sync">Disconnect:</label></th>
                <th><label for="postsync_manage_sync">Trash/Restore:</label></th>
                <th><label for="postsync_manage_sync">Permanent Delete:</label></th>
            </tr>
            <tr>
                <?php foreach (['can_publish', 'can_disconnect', 'can_trashrestore', 'can_permdelete'] as $action) : ?>
                    <td>
                        <select class="js-example-basic-multiple regular-text" name="postsync_<?= $action ?>[]"
                                multiple="multiple">
                            <?php foreach ($preparedData as $data) : ?>
                                <option value="<?= $data['blog_id'] ?>" <?= selected($data[$action]) ?>><?= $data['blog_name'] ?></option>
                            <?php endforeach; ?>
                        </select>
                    </td>
                <?php endforeach; ?>
            </tr>
        </table>
        <?php
    }


    /**
     * Saves the custom user profile fields
     * @param $user_id
     * @return false|void
     */
    public function save_custom_user_profile_fields($user_id)
    {
        if (!current_user_can('edit_user', $user_id)) {
            return false;
        }

        // Get all blogs/sites
        $blogs = get_sites();

        // Get the user data
        $user = get_userdata($user_id);

        // List of all capabilities
        $capabilities = ['postsync_can_publish', 'postsync_can_disconnect', 'postsync_can_trashrestore', 'postsync_can_permdelete'];

        foreach ($blogs as $blog) {
            switch_to_blog($blog->blog_id);

            foreach ($capabilities as $capability) {
                // Remove the capability
                $user->remove_cap($capability);

                // If this blog is selected, add the capability
                if (isset($_POST[$capability]) && in_array($blog->blog_id, $_POST[$capability])) {
                    $user->add_cap($capability);
                }
            }

            restore_current_blog();
        }
    }
}