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

/**
 * Účty správců webu nedostávají zákaznickou roli z produktu.
 *
 * @param int|WP_User $user
 * @return bool
 */
function elementsell_user_should_receive_product_role( $user ) {
    if ( ! $user instanceof WP_User ) {
        $user = get_user_by( 'id', (int) $user );
    }

    if ( ! $user ) {
        return true;
    }

    return ! user_can( $user, 'manage_options' );
}

/**
 * @param string $email
 * @return bool
 */
function elementsell_email_belongs_to_site_admin( $email ) {
    $user = get_user_by( 'email', sanitize_email( (string) $email ) );

    if ( ! $user ) {
        return false;
    }

    return ! elementsell_user_should_receive_product_role( $user );
}

/**
 * @param string $product_name
 * @return array{key: string, label: string}
 */
function elementsell_get_product_role_data( $product_name ) {
    $label = trim( (string) $product_name );
    $key   = elementsell_sanitize_product_role_key( $label );

    return [
        'key'   => $key,
        'label' => $label !== '' ? $label : $key,
    ];
}

/**
 * @param string $product_name
 * @return string|false
 */
function elementsell_ensure_product_role( $product_name ) {
    $role = elementsell_get_product_role_data( $product_name );

    if ( $role['key'] === '' ) {
        return false;
    }

    if ( ! get_role( $role['key'] ) ) {
        add_role(
            $role['key'],
            $role['label'],
            [
                'read'          => true,
                'edit_posts'    => false,
                'delete_posts'  => false,
                'publish_posts' => false,
            ]
        );
    }

    return $role['key'];
}

/**
 * @return string[]
 */
function elementsell_get_protected_role_keys() {
    return [
        'administrator',
        'editor',
        'author',
        'contributor',
        'subscriber',
    ];
}

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

    if ( $role_key === '' || ! get_role( $role_key ) ) {
        return '';
    }

    return $role_key;
}

/**
 * @return string[]
 */
function elementsell_get_noise_role_prefixes() {
    return apply_filters(
        'elementsell_noise_role_prefixes',
        [
            'wpie_',
            'wpamelia-',
            'wpamelia',
        ]
    );
}

/**
 * @param string $role_key
 * @return bool
 */
function elementsell_is_noise_plugin_role( $role_key ) {
    $role_key = (string) $role_key;

    foreach ( elementsell_get_noise_role_prefixes() as $prefix ) {
        if ( strncmp( $role_key, $prefix, strlen( $prefix ) ) === 0 ) {
            return true;
        }
    }

    return false;
}

/**
 * Všechny role skutečně uložené v WordPressu (stejný zdroj jako wp_roles()->roles).
 *
 * @return array<string, array{name: string, capabilities: array}>
 */
function elementsell_get_registered_wordpress_roles() {
    if ( ! function_exists( 'wp_roles' ) ) {
        return [];
    }

    $roles = [];

    foreach ( wp_roles()->roles as $role_key => $role_data ) {
        if ( get_role( $role_key ) ) {
            $roles[ (string) $role_key ] = $role_data;
        }
    }

    return $roles;
}

/**
 * @return string[]
 */
function elementsell_get_demo_course_role_keys() {
    return [
        'kurz_zaklady',
        'kurz_rytmus',
        'kurz_akordy',
        'kurz_fingerstyle',
        'kurz_profi',
    ];
}

/**
 * @param string $role_key
 * @return bool
 */
function elementsell_is_demo_course_role( $role_key ) {
    return in_array( (string) $role_key, elementsell_get_demo_course_role_keys(), true );
}

/**
 * Demo kytarové kurzy jsou vypnuté — smaž leftover WordPress role z dřívějšího dema.
 *
 * @return void
 */
function elementsell_maybe_cleanup_demo_course_roles() {
    if ( defined( 'ELEMENTSELL_DEMO_COURSES_ENABLED' ) && ELEMENTSELL_DEMO_COURSES_ENABLED ) {
        return;
    }

    if ( ! function_exists( 'get_role' ) || ! function_exists( 'elementsell_delete_role' ) ) {
        return;
    }

    foreach ( elementsell_get_demo_course_role_keys() as $role_key ) {
        if ( get_role( $role_key ) ) {
            elementsell_delete_role( $role_key );
        }
    }
}

add_action( 'admin_init', 'elementsell_maybe_cleanup_demo_course_roles', 3 );

/**
 * @param WP_User|null $user
 * @return array<string, array{title: string, roles: array<string, array>, deletable: bool}>
 */
function elementsell_get_role_admin_sections( $user = null ) {
    $registered_roles = elementsell_get_registered_wordpress_roles();
    $standard_roles   = elementsell_get_protected_role_keys();
    $user_roles       = ( $user instanceof WP_User && ! empty( $user->roles ) ) ? (array) $user->roles : [];

    $sections = [
        'standard' => [
            'title'     => 'Základní WordPress role',
            'roles'     => [],
            'deletable' => false,
        ],
        'course'   => [
            'title'     => 'Kurzové role',
            'roles'     => [],
            'deletable' => true,
        ],
        'system'   => [
            'title'     => 'Systémové role pluginů',
            'roles'     => [],
            'deletable' => false,
        ],
    ];

    foreach ( $registered_roles as $role_key => $role_data ) {
        if ( in_array( $role_key, $standard_roles, true ) ) {
            $sections['standard']['roles'][ $role_key ] = $role_data;
            continue;
        }

        if ( elementsell_is_noise_plugin_role( $role_key ) ) {
            $sections['system']['roles'][ $role_key ] = $role_data;
            continue;
        }

        $sections['course']['roles'][ $role_key ] = $role_data;
    }

    return $sections;
}

/**
 * Role zobrazené v adminu u uživatele — stejný zdroj jako wp_roles()->roles.
 *
 * @param WP_User|null $user
 * @return array<string, array{name: string, capabilities: array}>
 */
function elementsell_get_roles_for_user_admin( $user = null ) {
    return elementsell_get_registered_wordpress_roles();
}

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

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

    return ! in_array( $role_key, elementsell_get_protected_role_keys(), true );
}

/**
 * @param string $role_key
 * @return true|WP_Error
 */
function elementsell_delete_role( $role_key ) {
    $role_key = elementsell_validate_registered_role_key( $role_key );

    if ( $role_key === '' ) {
        return new WP_Error( 'elementsell_role_missing', 'Role neexistuje.' );
    }

    if ( ! elementsell_is_role_deletable( $role_key ) ) {
        return new WP_Error( 'elementsell_role_protected', 'Tuto roli nelze smazat.' );
    }

    $users = get_users(
        [
            'role'   => $role_key,
            'fields' => 'ID',
        ]
    );

    $default_role = get_option( 'default_role', 'subscriber' );

    foreach ( $users as $user_id ) {
        $user = new WP_User( (int) $user_id );
        $user->remove_role( $role_key );

        if ( empty( $user->roles ) && get_role( $default_role ) ) {
            $user->set_role( $default_role );
        }
    }

    remove_role( $role_key );

    return true;
}

/**
 * @param int $order_id
 * @return bool
 */
function elementsell_should_send_login_credentials( $order_id ) {
    return (int) elementsell_get_order_field( $order_id, 'vytvorit_profil' ) === 1;
}

/**
 * Porovná hostitele URL bez ohledu na www.
 *
 * @param string $host_a
 * @param string $host_b
 * @return bool
 */
function elementsell_url_hosts_match( $host_a, $host_b ) {
    $normalize_host = static function ( $host ) {
        $host = strtolower( trim( (string) $host ) );

        if ( strpos( $host, 'www.' ) === 0 ) {
            return substr( $host, 4 );
        }

        return $host;
    };

    if ( $host_a === '' || $host_b === '' ) {
        return false;
    }

    return $normalize_host( $host_a ) === $normalize_host( $host_b );
}

/**
 * Sestaví plnou URL na tomto webu z cesty a volitelných query/fragment parametrů.
 *
 * @param string $path
 * @param string $query
 * @param string $fragment
 * @return string
 */
function elementsell_build_home_url_from_path( $path, $query = '', $fragment = '' ) {
    $path = '/' . ltrim( (string) $path, '/' );
    $url  = home_url( $path );

    if ( is_string( $query ) && $query !== '' ) {
        $url .= '?' . $query;
    }

    if ( is_string( $fragment ) && $fragment !== '' ) {
        $url .= '#' . $fragment;
    }

    return esc_url_raw( $url );
}

/**
 * Převede relativní nebo absolutní URL na plnou adresu na tomto webu.
 * Podporuje formáty: diky, /diky, https://example.com/diky (včetně www).
 *
 * @param string $url
 * @param string $fallback
 * @return string
 */
function elementsell_normalize_page_url( $url, $fallback = '' ) {
    $url = trim( (string) $url );

    if ( $url === '' ) {
        return $fallback !== '' ? esc_url_raw( $fallback ) : '';
    }

    if ( preg_match( '#^https?://#i', $url ) ) {
        $normalized = esc_url_raw( $url );

        if ( $normalized === '' ) {
            return $fallback !== '' ? esc_url_raw( $fallback ) : '';
        }

        $site_host = wp_parse_url( home_url(), PHP_URL_HOST );
        $url_host  = wp_parse_url( $normalized, PHP_URL_HOST );

        if ( $site_host && $url_host && elementsell_url_hosts_match( $site_host, $url_host ) ) {
            return elementsell_build_home_url_from_path(
                (string) wp_parse_url( $normalized, PHP_URL_PATH ),
                (string) wp_parse_url( $normalized, PHP_URL_QUERY ),
                (string) wp_parse_url( $normalized, PHP_URL_FRAGMENT )
            );
        }

        return $normalized;
    }

    return elementsell_build_home_url_from_path( $url );
}

/**
 * @param string $url
 * @return string
 */
function elementsell_normalize_login_redirect_url( $url ) {
    $normalized = elementsell_normalize_page_url( $url );

    if ( $normalized !== '' ) {
        return $normalized;
    }

    return home_url( '/' );
}

/**
 * @param int    $user_id
 * @param string $login_url
 * @return void
 */
function elementsell_save_customer_login_redirect( $user_id, $login_url ) {
    $redirect = elementsell_normalize_login_redirect_url( $login_url );

    update_user_meta( $user_id, 'elementsell_post_login_url', $redirect );
}

/**
 * @param int $user_id
 * @return string
 */
function elementsell_get_post_login_url_for_user( $user_id = 0 ) {
    $user_id = $user_id > 0 ? $user_id : get_current_user_id();

    if ( $user_id <= 0 ) {
        return '';
    }

    $stored = get_user_meta( $user_id, 'elementsell_post_login_url', true );

    if ( is_string( $stored ) && $stored !== '' ) {
        return elementsell_normalize_login_redirect_url( $stored );
    }

    $user = get_userdata( $user_id );

    if ( ! $user || empty( $user->user_email ) ) {
        return '';
    }

    global $wpdb;

    $login_url = $wpdb->get_var(
        $wpdb->prepare(
            "SELECT f_login.field_value
             FROM {$wpdb->prefix}elementsell_orders o
             INNER JOIN {$wpdb->prefix}elementsell_order_fields f_done
                ON f_done.order_id = o.id
                AND f_done.field_name = 'access_completed_at'
                AND f_done.field_value != ''
             INNER JOIN {$wpdb->prefix}elementsell_order_fields f_login
                ON f_login.order_id = o.id
                AND f_login.field_name = 'login_url'
             WHERE LOWER(o.email) = LOWER(%s)
             AND f_login.field_value != ''
             ORDER BY o.id DESC
             LIMIT 1",
            $user->user_email
        )
    );

    if ( ! is_string( $login_url ) || $login_url === '' ) {
        return '';
    }

    return elementsell_normalize_login_redirect_url( $login_url );
}

/**
 * Vytvoří nebo aktualizuje WP účet pro objednávku.
 *
 * @param object $order
 * @return WP_User|false
 */
function elementsell_setup_customer_account_for_order( $order ) {
    if ( ! $order || empty( $order->email ) || ! is_email( $order->email ) ) {
        return false;
    }

    $role_keys = elementsell_get_order_role_keys( $order );

    if ( empty( $role_keys ) ) {
        return false;
    }

    $primary_role = $role_keys[0];
    $email        = sanitize_email( $order->email );
    $user         = get_user_by( 'email', $email );

    if ( $user ) {
        elementsell_assign_order_roles_to_user( $user, $order );

        return $user;
    }

    add_filter( 'wp_send_new_user_notifications', '__return_false' );

    $user_id = wp_insert_user(
        [
            'user_login' => $email,
            'user_email' => $email,
            'user_pass'  => wp_generate_password( 24, true, true ),
            'role'       => $primary_role,
        ]
    );

    remove_filter( 'wp_send_new_user_notifications', '__return_false' );

    if ( is_wp_error( $user_id ) ) {
        error_log( 'ElementSell: chyba vytvoření uživatele: ' . $user_id->get_error_message() );
        return false;
    }

    update_user_meta( (int) $user_id, 'elementsell_created_for_order_id', (int) $order->id );

    $user = get_user_by( 'id', $user_id );

    if ( ! $user ) {
        return false;
    }

    elementsell_assign_order_roles_to_user( $user, $order );

    return $user;
}

/**
 * Připraví účet, vytvoří token a vrátí HTML tlačítka do e-mailu.
 *
 * @param object $order
 * @return string
 */
function elementsell_prepare_customer_login_for_order( $order ) {
    if ( ! elementsell_should_send_login_credentials( (int) $order->id ) ) {
        return '';
    }

    if ( ! elementsell_setup_customer_account_for_order( $order ) ) {
        error_log( 'ElementSell: nelze připravit účet zákazníka pro objednávku ' . (int) $order->id );
        return '';
    }

    return elementsell_build_access_button_html( $order );
}
