<?php
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

define( 'ELEMENTSELL_USER_ROLES_UI_BUILD', '2026-07-14.9' );

add_action( 'show_user_profile', 'elementsell_render_user_roles_field' );
add_action( 'edit_user_profile', 'elementsell_render_user_roles_field' );
add_action( 'user_new_form', 'elementsell_render_user_roles_field' );
add_action( 'profile_update', 'elementsell_save_user_roles_field', 99, 2 );
add_action( 'user_register', 'elementsell_save_user_roles_field', 99, 2 );
add_action( 'admin_enqueue_scripts', 'elementsell_enqueue_user_roles_admin_assets' );
add_action( 'admin_init', 'elementsell_handle_delete_role_request', 5 );
add_action( 'admin_notices', 'elementsell_render_role_delete_notices' );

/**
 * @param string $hook
 * @return void
 */
function elementsell_enqueue_user_roles_admin_assets( $hook ) {
    if ( ! in_array( $hook, [ 'user-edit.php', 'user-new.php', 'profile.php' ], true ) ) {
        return;
    }

    if ( ! current_user_can( 'promote_users' ) ) {
        return;
    }

    wp_register_style( 'elementsell-user-roles-admin', false );
    wp_enqueue_style( 'elementsell-user-roles-admin' );
    wp_add_inline_style(
        'elementsell-user-roles-admin',
        'tr.user-role-wrap { display: none; }
        .elementsell-role-list {
            display: flex;
            flex-direction: column;
            gap: 8px;
            max-width: 720px;
        }
        .elementsell-role-row {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 6px 10px;
            width: 100%;
            margin: 0;
            padding: 8px 10px;
            background: #f6f7f7;
            border: 1px solid #dcdcde;
            border-radius: 4px;
            box-sizing: border-box;
        }
        .elementsell-role-row label {
            display: inline-flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 6px;
            margin: 0;
        }
        .elementsell-role-row code {
            color: #646970;
        }
        .elementsell-role-row .elementsell-role-badge {
            font-size: 11px;
            color: #646970;
            font-style: italic;
        }
        .elementsell-role-row .elementsell-role-delete {
            margin-left: auto;
            display: inline-block;
            padding: 4px 12px;
            border: 1px solid #b32d2e;
            border-radius: 4px;
            background: #fcf0f1;
            color: #b32d2e !important;
            font-size: 12px;
            font-weight: 600;
            line-height: 1.4;
            text-decoration: none;
            white-space: nowrap;
        }
        .elementsell-role-row .elementsell-role-delete:hover,
        .elementsell-role-row .elementsell-role-delete:focus {
            background: #b32d2e;
            color: #fff !important;
        }
        .elementsell-role-help {
            margin: 0 0 14px;
            max-width: 720px;
            color: #50575e;
            font-size: 13px;
            line-height: 1.5;
        }
        .elementsell-role-section-title {
            margin: 14px 0 6px;
            font-size: 12px;
            font-weight: 700;
            letter-spacing: 0.02em;
            text-transform: uppercase;
            color: #646970;
        }
        .elementsell-role-section-title:first-child {
            margin-top: 0;
        }
        .elementsell-role-system details {
            margin-top: 12px;
            max-width: 720px;
        }
        .elementsell-role-system summary {
            cursor: pointer;
            color: #646970;
            font-size: 13px;
        }
        .elementsell-role-system .elementsell-role-list {
            margin-top: 8px;
        }
        .elementsell-role-row--system {
            opacity: 0.85;
        }'
    );
}

/**
 * @param string $role_key
 * @return string
 */
function elementsell_get_role_delete_nonce_action( $role_key ) {
    return 'elementsell_delete_role_' . md5( (string) $role_key );
}

/**
 * @return string
 */
function elementsell_get_role_delete_redirect_base_url() {
    if ( isset( $_GET['user_id'] ) ) {
        $user_id = (int) $_GET['user_id'];

        if ( $user_id > 0 ) {
            return add_query_arg( 'user_id', $user_id, admin_url( 'user-edit.php' ) );
        }
    }

    return admin_url( 'users.php' );
}

/**
 * @param string $role_key
 * @return string
 */
function elementsell_get_delete_role_url( $role_key ) {
    $role_key = elementsell_validate_registered_role_key( $role_key );

    if ( $role_key === '' ) {
        return '';
    }

    return wp_nonce_url(
        add_query_arg(
            'elementsell_delete_role',
            $role_key,
            elementsell_get_role_delete_redirect_base_url()
        ),
        elementsell_get_role_delete_nonce_action( $role_key )
    );
}

/**
 * @return void
 */
function elementsell_handle_delete_role_request() {
    if ( ! isset( $_GET['elementsell_delete_role'] ) ) {
        return;
    }

    if ( ! current_user_can( 'manage_options' ) ) {
        wp_die( esc_html__( 'Nemáte oprávnění smazat roli.', 'platebni-formular' ) );
    }

    $role_key = isset( $_GET['elementsell_delete_role'] )
        ? wp_unslash( (string) $_GET['elementsell_delete_role'] )
        : '';
    $role_key = elementsell_validate_registered_role_key( $role_key );

    if ( $role_key === '' ) {
        wp_die( esc_html__( 'Neplatný požadavek — role neexistuje nebo je poškozená URL.', 'platebni-formular' ) );
    }

    if (
        empty( $_GET['_wpnonce'] )
        || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), elementsell_get_role_delete_nonce_action( $role_key ) )
    ) {
        wp_die( esc_html__( 'Neplatný požadavek.', 'platebni-formular' ) );
    }

    $redirect = remove_query_arg(
        [ 'elementsell_delete_role', 'elementsell_role_deleted', 'elementsell_role_error', '_wpnonce' ],
        wp_get_referer() ?: elementsell_get_role_delete_redirect_base_url()
    );

    $result = elementsell_delete_role( $role_key );

    if ( is_wp_error( $result ) ) {
        wp_safe_redirect(
            add_query_arg(
                'elementsell_role_error',
                rawurlencode( $result->get_error_message() ),
                $redirect
            )
        );
        exit;
    }

    wp_safe_redirect(
        add_query_arg(
            'elementsell_role_deleted',
            $role_key,
            $redirect
        )
    );
    exit;
}

/**
 * @return void
 */
function elementsell_render_role_delete_notices() {
    if ( ! in_array( get_current_screen() ? get_current_screen()->id : '', [ 'user-edit', 'profile', 'user', 'users' ], true ) ) {
        return;
    }

    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }

    if ( isset( $_GET['elementsell_role_deleted'] ) ) {
        $role_key = wp_unslash( (string) $_GET['elementsell_role_deleted'] );
        ?>
        <div class="notice notice-success is-dismissible">
            <p>Role <code><?php echo esc_html( $role_key ); ?></code> byla smazána.</p>
        </div>
        <?php
    }

    if ( isset( $_GET['elementsell_role_error'] ) ) {
        ?>
        <div class="notice notice-error is-dismissible">
            <p><?php echo esc_html( wp_unslash( (string) $_GET['elementsell_role_error'] ) ); ?></p>
        </div>
        <?php
    }
}

/**
 * @param string               $role_key
 * @param array<string, mixed> $role_data
 * @param string[]             $user_roles
 * @param bool                 $allow_delete
 * @return void
 */
function elementsell_render_user_role_row( $role_key, $role_data, $user_roles, $allow_delete ) {
    $row_class = $allow_delete ? 'elementsell-role-row' : 'elementsell-role-row elementsell-role-row--system';
    $is_demo   = function_exists( 'elementsell_is_demo_course_role' ) && elementsell_is_demo_course_role( $role_key );
    ?>
    <div class="<?php echo esc_attr( $row_class ); ?>">
        <label>
            <input
                type="checkbox"
                name="elementsell_user_roles[]"
                value="<?php echo esc_attr( $role_key ); ?>"
                <?php checked( in_array( $role_key, $user_roles, true ) ); ?>
            >
            <span><?php echo esc_html( translate_user_role( $role_data['name'] ) ); ?></span>
            <code><?php echo esc_html( $role_key ); ?></code>
            <?php if ( $is_demo ) : ?>
                <span class="elementsell-role-badge">demo ElementSell</span>
            <?php endif; ?>
        </label>
        <?php if ( $allow_delete && current_user_can( 'manage_options' ) && elementsell_is_role_deletable( $role_key ) ) : ?>
            <a
                href="<?php echo esc_url( elementsell_get_delete_role_url( $role_key ) ); ?>"
                class="elementsell-role-delete"
                onclick="return confirm('Opravdu smazat roli „<?php echo esc_js( translate_user_role( $role_data['name'] ) ); ?>“ (<?php echo esc_js( $role_key ); ?>)? Odstraní se všem uživatelům na webu.');"
            >Smazat roli</a>
        <?php endif; ?>
    </div>
    <?php
}

/**
 * @param WP_User $user
 * @return void
 */
function elementsell_render_user_roles_field( $user ) {
    if ( ! current_user_can( 'promote_users' ) ) {
        return;
    }

    if ( ! function_exists( 'elementsell_get_role_admin_sections' ) ) {
        return;
    }

    $sections         = elementsell_get_role_admin_sections( $user instanceof WP_User ? $user : null );
    $registered_count = count( elementsell_get_registered_wordpress_roles() );
    $course_count     = count( $sections['course']['roles'] );
    $system_count     = count( $sections['system']['roles'] );

    $user_roles = [];

    if ( $user instanceof WP_User && ! empty( $user->roles ) ) {
        $user_roles = (array) $user->roles;
    }

    wp_nonce_field( 'elementsell_save_user_roles', 'elementsell_user_roles_nonce' );
    ?>
    <h2 data-es-user-roles="<?php echo esc_attr( ELEMENTSELL_USER_ROLES_UI_BUILD ); ?>">Role uživatele</h2>
    <p class="elementsell-role-help">
        Seznam vychází přímo z <code>wp_roles()-&gt;roles</code>.
        V databázi je <strong><?php echo (int) $registered_count; ?></strong> rolí,
        z toho <strong><?php echo (int) $course_count; ?></strong> kurzových.
        Kurzové role vznikají z názvu produktu po zaplacení — nepotřebné lze smazat.
    </p>
    <?php if ( in_array( 'administrator', $user_roles, true ) && count( $user_roles ) > 1 ) : ?>
        <div class="notice notice-warning inline" style="margin: 0 0 16px; padding: 10px 12px;">
            <p style="margin: 0;">
                <strong>Pozor:</strong> Účet má roli Administrator a zároveň další role.
                To může rozbít Elementor editor. Správcům webu nechte jen roli Administrator.
            </p>
        </div>
    <?php endif; ?>
    <table class="form-table elementsell-user-roles-table" role="presentation">
        <tr>
            <th scope="row">Přiřazené role</th>
            <td>
                <fieldset>
                    <legend class="screen-reader-text"><span>Role uživatele</span></legend>
                    <div class="elementsell-role-list">
                        <?php if ( ! empty( $sections['standard']['roles'] ) ) : ?>
                            <div class="elementsell-role-section-title"><?php echo esc_html( $sections['standard']['title'] ); ?></div>
                            <?php foreach ( $sections['standard']['roles'] as $role_key => $role_data ) : ?>
                                <?php elementsell_render_user_role_row( $role_key, $role_data, $user_roles, false ); ?>
                            <?php endforeach; ?>
                        <?php endif; ?>

                        <?php if ( ! empty( $sections['course']['roles'] ) ) : ?>
                            <div class="elementsell-role-section-title"><?php echo esc_html( $sections['course']['title'] ); ?></div>
                            <?php foreach ( $sections['course']['roles'] as $role_key => $role_data ) : ?>
                                <?php elementsell_render_user_role_row( $role_key, $role_data, $user_roles, true ); ?>
                            <?php endforeach; ?>
                        <?php else : ?>
                            <div class="elementsell-role-section-title"><?php echo esc_html( $sections['course']['title'] ); ?></div>
                            <p class="elementsell-role-help" style="margin:0;">Žádné kurzové role v databázi.</p>
                        <?php endif; ?>
                    </div>

                    <?php if ( $system_count > 0 ) : ?>
                        <div class="elementsell-role-system">
                            <details>
                                <summary>Systémové role jiných pluginů (<?php echo (int) $system_count; ?>) — Amelia, WP Import Export…</summary>
                                <div class="elementsell-role-list">
                                    <?php foreach ( $sections['system']['roles'] as $role_key => $role_data ) : ?>
                                        <?php elementsell_render_user_role_row( $role_key, $role_data, $user_roles, false ); ?>
                                    <?php endforeach; ?>
                                </div>
                            </details>
                        </div>
                    <?php endif; ?>
                </fieldset>
            </td>
        </tr>
    </table>
    <?php
}

/**
 * @param int $user_id
 * @return void
 */
function elementsell_save_user_roles_field( $user_id ) {
    if ( ! current_user_can( 'promote_users' ) ) {
        return;
    }

    if (
        empty( $_POST['elementsell_user_roles_nonce'] )
        || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['elementsell_user_roles_nonce'] ) ), 'elementsell_save_user_roles' )
    ) {
        return;
    }

    $selected_roles = [];

    if ( isset( $_POST['elementsell_user_roles'] ) && is_array( $_POST['elementsell_user_roles'] ) ) {
        foreach ( wp_unslash( $_POST['elementsell_user_roles'] ) as $role_key ) {
            $role_key = elementsell_validate_registered_role_key( (string) $role_key );

            if ( $role_key !== '' ) {
                $selected_roles[] = $role_key;
            }
        }
    }

    $editable_roles = array_keys( elementsell_get_registered_wordpress_roles() );
    $selected_roles = array_values( array_intersect( $selected_roles, $editable_roles ) );

    if ( empty( $selected_roles ) ) {
        $selected_roles = [ get_option( 'default_role', 'subscriber' ) ];
    }

    $user = new WP_User( (int) $user_id );

    if ( ! $user->exists() ) {
        return;
    }

    foreach ( (array) $user->roles as $role_key ) {
        if ( ! in_array( $role_key, $selected_roles, true ) ) {
            $user->remove_role( $role_key );
        }
    }

    foreach ( $selected_roles as $role_key ) {
        if ( ! in_array( $role_key, (array) $user->roles, true ) ) {
            $user->add_role( $role_key );
        }
    }
}
