<?php

/**
 * Profile Fields helper functions
 *
 * @package ArraySubs\Functions
 * @since 1.9.0
 */

defined('ABSPATH') || exit;

/**
 * Get profile fields configuration.
 *
 * @return array Array of field definitions.
 */
function arraysubs_get_profile_fields_config(): array
{
    $config = get_option('arraysubs_profile_fields_config', []);

    if (!is_array($config)) {
        return [];
    }

    return $config;
}

/**
 * Save profile fields configuration.
 *
 * @param array $config Array of field definitions.
 * @return bool
 */
function arraysubs_save_profile_fields_config(array $config): bool
{
    $sanitized = arraysubs_sanitize_profile_fields_config($config);
    return update_option('arraysubs_profile_fields_config', $sanitized);
}

/**
 * Get avatar settings.
 *
 * @return array
 */
function arraysubs_get_avatar_settings(): array
{
    $defaults = [
        'enabled'       => false,
        'max_file_size' => 2,
        'allowed_types' => ['jpg', 'jpeg', 'png', 'gif', 'webp'],
    ];

    $settings = get_option('arraysubs_avatar_settings', $defaults);

    if (!is_array($settings)) {
        return $defaults;
    }

    return wp_parse_args($settings, $defaults);
}

/**
 * Save avatar settings.
 *
 * @param array $settings Avatar settings.
 * @return bool
 */
function arraysubs_save_avatar_settings(array $settings): bool
{
    $valid_image_types = ['jpg', 'jpeg', 'png', 'gif', 'webp'];

    $sanitized = [
        'enabled'       => !empty($settings['enabled']),
        'max_file_size' => min(absint($settings['max_file_size'] ?? 2), 100),
        'allowed_types' => array_values(array_intersect(
            array_map('sanitize_text_field', (array) ($settings['allowed_types'] ?? $valid_image_types)),
            $valid_image_types
        )),
    ];

    return update_option('arraysubs_avatar_settings', $sanitized);
}

/**
 * Sanitize profile fields configuration.
 *
 * @param array $config Raw configuration.
 * @return array Sanitized configuration.
 */
function arraysubs_sanitize_profile_fields_config(array $config): array
{
    $allowed_types = ['text', 'textarea', 'select', 'date', 'checkbox', 'upload'];
    $sanitized     = [];

    foreach ($config as $index => $field) {
        if (!is_array($field) || empty($field['key']) || empty($field['type'])) {
            continue;
        }

        $type = sanitize_text_field($field['type']);

        if (!in_array($type, $allowed_types, true)) {
            continue;
        }

        $key = sanitize_key($field['key']);

        if (empty($key)) {
            continue;
        }

        $sanitized_field = [
            'key'         => $key,
            'label'       => sanitize_text_field($field['label'] ?? ''),
            'type'        => $type,
            'required'    => !empty($field['required']),
            'placeholder' => sanitize_text_field($field['placeholder'] ?? ''),
            'help_text'   => sanitize_text_field($field['help_text'] ?? ''),
            'enabled'     => isset($field['enabled']) ? (bool) $field['enabled'] : true,
            'position'    => absint($field['position'] ?? $index),
        ];

        if ('select' === $type && !empty($field['options']) && is_array($field['options'])) {
            $sanitized_field['options'] = [];
            foreach ($field['options'] as $option) {
                if (!is_array($option) || !isset($option['value'])) {
                    continue;
                }
                $sanitized_field['options'][] = [
                    'value' => sanitize_text_field($option['value']),
                    'label' => sanitize_text_field($option['label'] ?? $option['value']),
                ];
            }
        }

        if ('upload' === $type) {
            $valid_upload_types               = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'pdf', 'doc', 'docx', 'xls', 'xlsx', 'csv', 'txt', 'zip'];
            $sanitized_field['allowed_types'] = array_values(array_intersect(
                array_map('sanitize_text_field', (array) ($field['allowed_types'] ?? ['jpg', 'jpeg', 'png', 'pdf', 'doc', 'docx'])),
                $valid_upload_types
            ));
            $sanitized_field['max_file_size'] = min(absint($field['max_file_size'] ?? 5), 100);
        }

        $sanitized[] = $sanitized_field;
    }

    usort($sanitized, function ($a, $b) {
        return $a['position'] <=> $b['position'];
    });

    return $sanitized;
}

/**
 * Get enabled profile fields.
 *
 * @return array Only enabled fields, sorted by position.
 */
function arraysubs_get_enabled_profile_fields(): array
{
    if (function_exists('arraysubs_is_custom_profile_fields_enabled') && !arraysubs_is_custom_profile_fields_enabled()) {
        return [];
    }

    $fields = arraysubs_get_profile_fields_config();
    return array_values(array_filter($fields, function ($field) {
        return !empty($field['enabled']);
    }));
}

/**
 * Get user profile field value.
 *
 * @param int    $user_id  User ID.
 * @param string $field_key Field key.
 * @return mixed
 */
function arraysubs_get_user_profile_field(int $user_id, string $field_key)
{
    return get_user_meta($user_id, 'arraysubs_pf_' . sanitize_key($field_key), true);
}

/**
 * Save user profile field value.
 *
 * @param int    $user_id    User ID.
 * @param string $field_key  Field key.
 * @param mixed  $value      Value to save.
 * @return bool|int
 */
function arraysubs_save_user_profile_field(int $user_id, string $field_key, $value)
{
    return update_user_meta($user_id, 'arraysubs_pf_' . sanitize_key($field_key), $value);
}

/**
 * Get user avatar data.
 *
 * @param int $user_id User ID.
 * @return array Avatar data with 'url' and 'file_path' keys.
 */
function arraysubs_get_user_avatar(int $user_id): array
{
    $avatar_file = get_user_meta($user_id, 'arraysubs_avatar', true);

    if (empty($avatar_file)) {
        return [
            'url'       => '',
            'file_path' => '',
            'has_avatar' => false,
        ];
    }

    $upload_dir = arraysubs_get_avatar_upload_dir();

    return [
        'url'        => $upload_dir['url'] . '/' . $avatar_file,
        'file_path'  => $upload_dir['path'] . '/' . $avatar_file,
        'has_avatar'  => true,
    ];
}

/**
 * Get avatar upload directory.
 *
 * @return array With 'path' and 'url' keys.
 */
function arraysubs_get_avatar_upload_dir(): array
{
    $upload_dir = wp_upload_dir();

    return [
        'path' => $upload_dir['basedir'] . '/arraysubs-avatars',
        'url'  => $upload_dir['baseurl'] . '/arraysubs-avatars',
    ];
}

/**
 * Get user file upload directory.
 *
 * @param int $user_id User ID.
 * @return array With 'path' and 'url' keys.
 */
function arraysubs_get_profile_upload_dir(int $user_id): array
{
    $upload_dir = wp_upload_dir();

    return [
        'path' => $upload_dir['basedir'] . '/arraysubs-profiles/' . $user_id,
        'url'  => $upload_dir['baseurl'] . '/arraysubs-profiles/' . $user_id,
    ];
}

/**
 * Delete user avatar file and meta.
 *
 * @param int $user_id User ID.
 * @return bool
 */
function arraysubs_delete_user_avatar(int $user_id): bool
{
    $avatar = arraysubs_get_user_avatar($user_id);

    if ($avatar['has_avatar'] && !empty($avatar['file_path']) && file_exists($avatar['file_path'])) {
        wp_delete_file($avatar['file_path']);
    }

    delete_user_meta($user_id, 'arraysubs_avatar');
    return true;
}

/**
 * Protect an upload directory with .htaccess and index.php.
 *
 * @param string $dir_path  Absolute path to the directory.
 * @param bool   $deny_all  Whether to deny all direct access (true for private files, false for avatars).
 * @return void
 */
function arraysubs_protect_upload_dir(string $dir_path, bool $deny_all = false): void
{
    $htaccess = $dir_path . '/.htaccess';
    if (!file_exists($htaccess)) {
        $rules = "Options -Indexes\n";
        if ($deny_all) {
            $rules .= "<Files *>\n";
            $rules .= "Require all denied\n";
            $rules .= "</Files>\n";
        }
        global $wp_filesystem;

        if (empty($wp_filesystem)) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
            WP_Filesystem();
        }

        $wp_filesystem->put_contents($htaccess, $rules, FS_CHMOD_FILE);
    }

    $index = $dir_path . '/index.php';
    if (!file_exists($index)) {
        global $wp_filesystem;

        if (empty($wp_filesystem)) {
            require_once ABSPATH . 'wp-admin/includes/file.php';
            WP_Filesystem();
        }

        $wp_filesystem->put_contents($index, "<?php\n// Silence is golden.\n", FS_CHMOD_FILE);
    }
}
