<?php

/**
 * Memory Hub admin page — free-compatible AJAX handlers.
 *
 * Handles Definitions tab endpoints of the Memory Hub: standalone variable
 * definitions, slide-defined variables (read-only), profile field selection,
 * and capture-code generation. Kept outside Premium/ so handlers remain
 * registered in the free zip.
 *
 * Learner CRUD (tab "Learner Data") lives in the Premium folder.
 *
 * @package SlideMind
 * @since 2.3.0
 */
namespace SlideMind\Admin;

use SlideMind\Core\FeatureGate;
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
class MemoryAdminPage {
    /**
     * Constructor — register AJAX hooks used by the Definitions tab.
     */
    public function __construct() {
        // Memory definitions endpoints
        add_action( 'wp_ajax_slidemind_get_memory_definitions', [$this, 'ajax_get_memory_definitions'] );
        add_action( 'wp_ajax_slidemind_save_memory_definition', [$this, 'ajax_save_memory_definition'] );
        add_action( 'wp_ajax_slidemind_delete_memory_definition', [$this, 'ajax_delete_memory_definition'] );
        add_action( 'wp_ajax_slidemind_delete_memory_definitions_bulk', [$this, 'ajax_delete_memory_definitions_bulk'] );
        add_action( 'wp_ajax_slidemind_get_slide_memory_definitions', [$this, 'ajax_get_slide_memory_definitions'] );
        add_action( 'wp_ajax_slidemind_generate_capture_code', [$this, 'ajax_generate_capture_code'] );
        // Profile fields endpoints
        add_action( 'wp_ajax_slidemind_get_profile_fields', [$this, 'ajax_get_profile_fields'] );
        add_action( 'wp_ajax_slidemind_save_profile_settings', [$this, 'ajax_save_profile_settings'] );
    }

    /**
     * AJAX: Returns central memory definitions enriched with learner counts.
     */
    public function ajax_get_memory_definitions() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        $definitions = get_option( 'slidemind_memory_definitions', [] );
        if ( !empty( $definitions ) ) {
            global $wpdb;
            $mem_table = $wpdb->prefix . 'slidemind_learner_memory';
            foreach ( $definitions as &$def ) {
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $def['learner_count'] = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT wp_user_id) FROM %i WHERE variable_name = %s", $mem_table, $def['name'] ) );
            }
            unset($def);
        }
        wp_send_json_success( [
            'definitions' => $definitions,
        ] );
    }

    /**
     * AJAX: Create or update a central memory definition.
     */
    public function ajax_save_memory_definition() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        $id = ( isset( $_POST['def_id'] ) ? sanitize_text_field( wp_unslash( $_POST['def_id'] ) ) : '' );
        $name = ( isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '' );
        $description = ( isset( $_POST['description'] ) ? sanitize_text_field( wp_unslash( $_POST['description'] ) ) : '' );
        if ( empty( $name ) ) {
            wp_send_json_error( [
                'message' => __( 'Variable name is required', 'slidemind' ),
            ] );
        }
        if ( !preg_match( '/^[a-z][a-z0-9_]*$/', $name ) ) {
            wp_send_json_error( [
                'message' => __( 'Variable name must start with a lowercase letter and contain only letters, numbers, and underscores.', 'slidemind' ),
            ] );
        }
        $definitions = get_option( 'slidemind_memory_definitions', [] );
        if ( !empty( $id ) ) {
            $found = false;
            foreach ( $definitions as &$def ) {
                if ( $def['id'] === $id ) {
                    $def['name'] = $name;
                    $def['description'] = $description;
                    unset($def['scope']);
                    // Remove legacy scope if present
                    $found = true;
                    break;
                }
            }
            unset($def);
            if ( !$found ) {
                wp_send_json_error( [
                    'message' => __( 'Definition not found', 'slidemind' ),
                ] );
            }
        } else {
            if ( in_array( $name, array_column( $definitions, 'name' ), true ) ) {
                wp_send_json_error( [
                    'message' => __( 'A variable with this name already exists.', 'slidemind' ),
                ] );
            }
            $definitions[] = [
                'id'          => uniqid( 'def_' ),
                'name'        => $name,
                'description' => $description,
                'created_at'  => gmdate( 'Y-m-d' ),
            ];
        }
        update_option( 'slidemind_memory_definitions', $definitions );
        wp_send_json_success( [
            'message'     => __( 'Definition saved', 'slidemind' ),
            'definitions' => $definitions,
        ] );
    }

    /**
     * AJAX: Delete a central memory definition.
     */
    public function ajax_delete_memory_definition() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        $id = ( isset( $_POST['def_id'] ) ? sanitize_text_field( wp_unslash( $_POST['def_id'] ) ) : '' );
        if ( empty( $id ) ) {
            wp_send_json_error( [
                'message' => __( 'Invalid definition ID', 'slidemind' ),
            ] );
        }
        $definitions = get_option( 'slidemind_memory_definitions', [] );
        $definitions = array_values( array_filter( $definitions, function ( $def ) use($id) {
            return $def['id'] !== $id;
        } ) );
        update_option( 'slidemind_memory_definitions', $definitions );
        wp_send_json_success( [
            'message'     => __( 'Definition deleted', 'slidemind' ),
            'definitions' => $definitions,
        ] );
    }

    /**
     * AJAX: Bulk-delete multiple central memory definitions in one atomic read-write.
     */
    public function ajax_delete_memory_definitions_bulk() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
        $raw_ids = ( isset( $_POST['def_ids'] ) ? wp_unslash( $_POST['def_ids'] ) : [] );
        if ( !is_array( $raw_ids ) ) {
            wp_send_json_error( [
                'message' => __( 'Invalid definition IDs', 'slidemind' ),
            ] );
        }
        $ids = array_map( 'sanitize_text_field', $raw_ids );
        $ids = array_filter( $ids );
        if ( empty( $ids ) ) {
            wp_send_json_error( [
                'message' => __( 'No definition IDs provided', 'slidemind' ),
            ] );
        }
        $definitions = get_option( 'slidemind_memory_definitions', [] );
        $definitions = array_values( array_filter( $definitions, function ( $def ) use($ids) {
            return !in_array( $def['id'], $ids, true );
        } ) );
        update_option( 'slidemind_memory_definitions', $definitions );
        wp_send_json_success( [
            'message'     => __( 'Definitions deleted', 'slidemind' ),
            'definitions' => $definitions,
        ] );
    }

    /**
     * AJAX: Aggregated view of memory variables defined across slides.
     */
    public function ajax_get_slide_memory_definitions() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        $plugin = \SlideMind\Plugin::instance();
        $config_repo = $plugin->get_config_repository();
        $slides = $config_repo->get_all_slides();
        global $wpdb;
        $mem_table = $wpdb->prefix . 'slidemind_learner_memory';
        $variables = [];
        foreach ( $slides as $slide ) {
            $memory_vars = $slide['memory_variables'] ?? [];
            if ( empty( $memory_vars ) ) {
                continue;
            }
            foreach ( $memory_vars as $mvar ) {
                if ( empty( $mvar['name'] ) ) {
                    continue;
                }
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $learner_count = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT wp_user_id) FROM %i WHERE variable_name = %s", $mem_table, $mvar['name'] ) );
                $variables[] = [
                    'name'          => $mvar['name'],
                    'scope'         => $mvar['scope'] ?? 'global',
                    'source'        => $mvar['source'] ?? '',
                    'slide_id'      => $slide['id'],
                    'slide_title'   => $slide['title'],
                    'module_title'  => $slide['parent_module_title'] ?? '',
                    'course_title'  => $slide['parent_course_title'] ?? $slide['parent_formation_title'] ?? '',
                    'learner_count' => $learner_count,
                ];
            }
            if ( !empty( $slide['save_user_input'] ) && $slide['save_user_input'] === '1' && !empty( $slide['save_input_key'] ) ) {
                $key = $slide['save_input_key'];
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $lc = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT wp_user_id) FROM %i WHERE variable_name = %s", $mem_table, $key ) );
                $variables[] = [
                    'name'          => $key,
                    'scope'         => $slide['save_interaction_scope'] ?? 'global',
                    'source'        => __( 'Auto-save (input)', 'slidemind' ),
                    'slide_id'      => $slide['id'],
                    'slide_title'   => $slide['title'],
                    'module_title'  => $slide['parent_module_title'] ?? '',
                    'course_title'  => $slide['parent_course_title'] ?? $slide['parent_formation_title'] ?? '',
                    'learner_count' => $lc,
                ];
            }
            if ( !empty( $slide['save_ai_response'] ) && $slide['save_ai_response'] === '1' && !empty( $slide['save_response_key'] ) ) {
                $key = $slide['save_response_key'];
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
                $lc = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(DISTINCT wp_user_id) FROM %i WHERE variable_name = %s", $mem_table, $key ) );
                $variables[] = [
                    'name'          => $key,
                    'scope'         => $slide['save_interaction_scope'] ?? 'global',
                    'source'        => __( 'Auto-save (response)', 'slidemind' ),
                    'slide_id'      => $slide['id'],
                    'slide_title'   => $slide['title'],
                    'module_title'  => $slide['parent_module_title'] ?? '',
                    'course_title'  => $slide['parent_course_title'] ?? $slide['parent_formation_title'] ?? '',
                    'learner_count' => $lc,
                ];
            }
        }
        wp_send_json_success( [
            'variables' => $variables,
        ] );
    }

    /**
     * AJAX: Generates capture-only integration code via a system-managed
     * hidden memory_bridge configuration.
     */
    public function ajax_generate_capture_code() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        $config_uid = $this->get_or_create_memory_bridge();
        if ( is_wp_error( $config_uid ) ) {
            wp_send_json_error( [
                'message' => $config_uid->get_error_message(),
            ] );
        }
        wp_send_json_success( [
            'config_id' => $config_uid,
            'rest_url'  => rest_url( 'slidemind/v2/' ),
        ] );
    }

    /**
     * Gets or creates the hidden memory_bridge configuration.
     *
     * Invisible slidemind_config post used as the configId for autonomous
     * global memory capture code (never appears in admin lists because its
     * _slidemind_config_type is 'memory_bridge').
     *
     * @return string|\WP_Error The config_uid or WP_Error on failure
     */
    private function get_or_create_memory_bridge() {
        $post_id = get_option( 'slidemind_global_memory_config_id', 0 );
        if ( $post_id ) {
            $post = get_post( $post_id );
            if ( $post && $post->post_status === 'publish' ) {
                $uid = get_post_meta( $post_id, '_slidemind_config_uid', true );
                if ( $uid ) {
                    return $uid;
                }
            }
        }
        $post_id = wp_insert_post( [
            'post_type'   => 'slidemind_config',
            'post_title'  => 'SlideMind Global Memory Bridge',
            'post_status' => 'publish',
        ], true );
        if ( is_wp_error( $post_id ) ) {
            return $post_id;
        }
        update_post_meta( $post_id, '_slidemind_config_type', 'memory_bridge' );
        $token = wp_generate_password( 8, false );
        $config_uid = 'sm-memory-bridge-' . $token;
        update_post_meta( $post_id, '_slidemind_config_uid', $config_uid );
        update_option( 'slidemind_global_memory_config_id', $post_id );
        return $config_uid;
    }

    // ═══════════════════════════════════════════════════════════════
    //  Profile Fields (Memory Hub > Definitions > Profile Variables)
    // ═══════════════════════════════════════════════════════════════
    /**
     * AJAX: Returns available profile fields with their checked/alias state.
     */
    public function ajax_get_profile_fields() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        try {
            $profile_fields = SettingsPage::get_available_profile_fields();
        } catch ( \Throwable $e ) {
            wp_send_json_error( [
                'message' => __( 'Error loading profile fields', 'slidemind' ) . ': ' . $e->getMessage(),
            ] );
        }
        $settings = get_option( 'slidemind_settings', [] );
        $allowed = $settings['allowed_profile_fields'] ?? [];
        $aliases = $settings['profile_field_aliases'] ?? [];
        $grouped = [];
        foreach ( $profile_fields as $field ) {
            $source = $field['source'];
            if ( !isset( $grouped[$source] ) ) {
                $grouped[$source] = [];
            }
            $grouped[$source][] = [
                'key'     => $field['key'],
                'label'   => $field['label'],
                'checked' => in_array( $field['key'], $allowed, true ),
                'alias'   => $aliases[$field['key']] ?? '',
            ];
        }
        // Baseline (free): show only sources that returned fields. In free this is WordPress only.
        $sources_meta = [];
        $ordered = [];
        foreach ( $grouped as $name => $fields ) {
            $ordered[$name] = $fields;
            $sources_meta[$name] = [
                'installed' => true,
            ];
        }
        wp_send_json_success( [
            'groups'       => $ordered,
            'sources_meta' => $sources_meta,
        ] );
    }

    /**
     * AJAX: Saves profile field settings (allowed fields + aliases).
     */
    public function ajax_save_profile_settings() {
        check_ajax_referer( 'slidemind_admin_nonce', 'nonce' );
        if ( !current_user_can( 'manage_slidemind_configs' ) ) {
            wp_send_json_error( [
                'message' => __( 'Unauthorized access', 'slidemind' ),
            ] );
        }
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Array data, sanitized in loop below
        $allowed_raw = ( isset( $_POST['allowed_profile_fields'] ) ? wp_unslash( $_POST['allowed_profile_fields'] ) : [] );
        // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Array data, sanitized in loop below
        $aliases_raw = ( isset( $_POST['profile_field_aliases'] ) ? wp_unslash( $_POST['profile_field_aliases'] ) : [] );
        if ( !is_array( $allowed_raw ) ) {
            $allowed_raw = [];
        }
        if ( !is_array( $aliases_raw ) ) {
            $aliases_raw = [];
        }
        $all_keys = array_column( SettingsPage::get_available_profile_fields(), 'key' );
        $native_keys = [
            'display_name',
            'email',
            'first_name',
            'last_name',
            'role'
        ];
        $valid_keys = array_values( array_intersect( $all_keys, $native_keys ) );
        $allowed = [];
        foreach ( $allowed_raw as $field ) {
            $field = sanitize_text_field( $field );
            if ( in_array( $field, $valid_keys, true ) ) {
                $allowed[] = $field;
            }
        }
        $aliases = [];
        foreach ( $aliases_raw as $original_key => $alias ) {
            $original_key = sanitize_text_field( $original_key );
            $alias = mb_strtolower( trim( $alias ) );
            $alias = preg_replace( '/[^\\p{L}0-9_]/u', '_', $alias );
            $alias = preg_replace( '/_+/', '_', $alias );
            $alias = trim( $alias, '_' );
            if ( !empty( $alias ) && in_array( $original_key, $valid_keys, true ) ) {
                $aliases[$original_key] = $alias;
            }
        }
        $settings = get_option( 'slidemind_settings', [] );
        $settings['allowed_profile_fields'] = $allowed;
        $settings['profile_field_aliases'] = $aliases;
        update_option( 'slidemind_settings', $settings );
        SettingsPage::clear_profile_fields_cache();
        wp_send_json_success( [
            'message' => __( 'Profile settings saved', 'slidemind' ),
        ] );
    }

}
