<?php

namespace AtlasAiDev\Awfah\REST;

use AtlasAiDev\Awfah\Plugin;
use AtlasAiDev\Awfah\Service\AI_Provider_Manager;
use AtlasAiDev\Awfah\Service\Error_Email_Notifier;
use AtlasAiDev\Awfah\Service\Error_Tracker;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Request;
use WP_REST_Response;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Settings_Controller extends WP_REST_Controller {

    public function __construct() {
        $this->namespace = 'awfah/v1';
        $this->rest_base = 'settings';
    }

    public function register_routes(): void {
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_settings' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'update_settings' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/usage',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_usage_stats' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                    'args'                => [
                        'from' => [
                            'type'              => 'string',
                            'format'            => 'date',
                            'required'          => false,
                            'sanitize_callback' => 'sanitize_text_field',
                        ],
                        'to' => [
                            'type'              => 'string',
                            'format'            => 'date',
                            'required'          => false,
                            'sanitize_callback' => 'sanitize_text_field',
                        ],
                    ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/dismiss-notice',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'dismiss_pro_notice' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        // Global default AI preference (provider + model). Used as the fallback when a
        // generation request does not specify its own provider/model.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/ai-preference',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_ai_preference' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'update_ai_preference' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                    'args'                => [
                        'provider' => [
                            'type'              => 'string',
                            'required'          => false,
                            'sanitize_callback' => 'sanitize_text_field',
                        ],
                        'model' => [
                            'type'              => 'string',
                            'required'          => false,
                            'sanitize_callback' => 'sanitize_text_field',
                        ],
                    ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/test-error-email',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'send_test_error_email' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/error-log-monitor',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_log_monitor_status' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/error-log-rescan',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'rescan_error_log' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/error-log-reset',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'reset_error_log_position' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        // Backup management endpoints (Pro delegates via filters).
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/backups',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_backups' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
                [
                    'methods'             => 'DELETE',
                    'callback'            => [ $this, 'delete_all_backups' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/backups/(?P<id>[a-zA-Z0-9_-]+)',
            [
                [
                    'methods'             => 'DELETE',
                    'callback'            => [ $this, 'delete_backup' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                    'args'                => [
                        'id' => [
                            'type'              => 'string',
                            'required'          => true,
                            'sanitize_callback' => 'sanitize_text_field',
                        ],
                    ],
                ],
            ]
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/backups/(?P<id>[a-zA-Z0-9_-]+)/restore',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'restore_backup' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                    'args'                => [
                        'id' => [
                            'type'              => 'string',
                            'required'          => true,
                            'sanitize_callback' => 'sanitize_text_field',
                        ],
                    ],
                ],
            ]
        );

        // Error groups (Phase 3).
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/error-groups',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_error_groups' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
                [
                    'methods'             => 'DELETE',
                    'callback'            => [ $this, 'clear_error_groups' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        // Error trends (Phase 4).
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/error-trends',
            [
                [
                    'methods'             => 'GET',
                    'callback'            => [ $this, 'get_error_trends' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        // Auto-fix (Phase 5).
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/auto-fix',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'execute_auto_fix' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );

        // Test webhook (Phase 6).
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/test-webhook',
            [
                [
                    'methods'             => 'POST',
                    'callback'            => [ $this, 'send_test_webhook' ],
                    'permission_callback' => [ $this, 'permissions_check' ],
                ],
            ]
        );
    }

    public function permissions_check(): bool {
        return current_user_can( 'manage_options' );
    }

    public function get_settings( WP_REST_Request $request ): WP_REST_Response {
        return new WP_REST_Response(
            [
                'settings' => Plugin::get_settings(),
                'roles'    => $this->get_wp_roles(),
                'version'  => AWFAH_VERSION,
            ]
        );
    }

    public function update_settings( WP_REST_Request $request ) {
        $params  = $request->get_json_params();
        $current = Plugin::get_settings();

        // Handle modules update.
        if ( isset( $params['modules'] ) && is_array( $params['modules'] ) ) {
            $current['modules'] = array_merge(
                $current['modules'],
                array_intersect_key(
                    $params['modules'],
                    $current['modules']
                )
            );

            // Prevent enabling store_manager when WooCommerce is not active.
            if ( ! empty( $current['modules']['store_manager'] ) && ! class_exists( 'WooCommerce' ) ) {
                $current['modules']['store_manager'] = false;
            }
        }

        // Handle role_abilities update.
        if ( isset( $params['role_abilities'] ) && is_array( $params['role_abilities'] ) ) {
            $current['role_abilities'] = $this->sanitize_role_abilities( $params['role_abilities'] );
        }

        // Handle role_workflows update.
        if ( isset( $params['role_workflows'] ) && is_array( $params['role_workflows'] ) ) {
            $current['role_workflows'] = $this->sanitize_role_workflows( $params['role_workflows'] );
        }

        // Handle error_notification settings update.
        if ( isset( $params['error_notification'] ) && is_array( $params['error_notification'] ) ) {
            $notif         = $params['error_notification'];
            $current_notif = $current['error_notification'] ?? Error_Email_Notifier::get_default_notification_settings();

            if ( isset( $notif['enabled'] ) ) {
                $current_notif['enabled'] = (bool) $notif['enabled'];
            }

            if ( isset( $notif['email'] ) ) {
                $email                  = sanitize_email( $notif['email'] );
                $current_notif['email'] = ( '' !== $email || '' === $notif['email'] ) ? $email : $current_notif['email'];
            }

            if ( isset( $notif['severities'] ) && is_array( $notif['severities'] ) ) {
                $valid_severities          = [ 'fatal', 'warning', 'notice', 'deprecated' ];
                $current_notif['severities'] = array_values(
                    array_intersect(
                        array_map( 'sanitize_key', $notif['severities'] ),
                        $valid_severities
                    )
                );
            }

            if ( isset( $notif['cooldown_minutes'] ) ) {
                $cooldown                          = (int) $notif['cooldown_minutes'];
                $current_notif['cooldown_minutes'] = max( 1, min( 1440, $cooldown ) );
            }



            if ( isset( $notif['sources'] ) && is_array( $notif['sources'] ) ) {
                $valid_sources     = [ 'plugin', 'theme', 'core', 'mu-plugin', 'drop-in' ];
                $sanitized_sources = array_values(
                    array_intersect(
                        array_map( 'sanitize_key', $notif['sources'] ),
                        $valid_sources
                    )
                );

                // Free version: only plugin and theme allowed.
                if ( ! awfah_is_pro_active() ) {
                    $free_sources      = [ 'plugin', 'theme' ];
                    $sanitized_sources = array_values( array_intersect( $sanitized_sources, $free_sources ) );
                    $sanitized_sources = array_slice( $sanitized_sources, 0, 2 );
                }

                $current_notif['sources'] = $sanitized_sources;
            }

            if ( isset( $notif['log_file_path'] ) ) {
                $path = sanitize_text_field( $notif['log_file_path'] );
                // Allow empty (auto-detect) or validate the path points to a readable file.
                $current_notif['log_file_path'] = $path;
            }

            // Webhook settings (Pro only).
            if ( isset( $notif['webhook_enabled'] ) ) {
                $current_notif['webhook_enabled'] = awfah_is_pro_active() && (bool) $notif['webhook_enabled'];
            }
            if ( isset( $notif['webhook_url'] ) ) {
                $current_notif['webhook_url'] = esc_url_raw( $notif['webhook_url'] );
            }
            if ( isset( $notif['webhook_channel'] ) ) {
                $valid_channels = [ 'slack', 'discord', 'custom' ];
                $channel        = sanitize_key( $notif['webhook_channel'] );
                if ( in_array( $channel, $valid_channels, true ) ) {
                    $current_notif['webhook_channel'] = $channel;
                }
            }
            if ( isset( $notif['webhook_events'] ) && is_array( $notif['webhook_events'] ) ) {
                $current_notif['webhook_events'] = array_values(
                    array_intersect(
                        array_map( 'sanitize_key', $notif['webhook_events'] ),
                        [ 'fatal', 'warning', 'notice', 'deprecated' ]
                    )
                );
            }

            // Dashboard widget toggle.
            if ( isset( $notif['show_dashboard_widget'] ) ) {
                $current_notif['show_dashboard_widget'] = (bool) $notif['show_dashboard_widget'];
            }

            // Trend settings (Pro only).
            if ( isset( $notif['weekly_digest'] ) ) {
                $current_notif['weekly_digest'] = awfah_is_pro_active() && (bool) $notif['weekly_digest'];
            }
            if ( isset( $notif['spike_alerts'] ) ) {
                $current_notif['spike_alerts'] = awfah_is_pro_active() && (bool) $notif['spike_alerts'];
            }

            $current['error_notification'] = $current_notif;
        }

        // Require at least one recognized key.
        if ( ! isset( $params['modules'] ) && ! isset( $params['role_abilities'] ) && ! isset( $params['role_workflows'] ) && ! isset( $params['error_notification'] ) ) {
            return new WP_Error(
                'awfah_invalid_settings',
                __( 'Invalid settings payload.', 'ai-workflow-automation-ai-agent-hub' ),
                [ 'status' => 400 ]
            );
        }

        Plugin::update_settings( $current );

        return new WP_REST_Response(
            [
                'settings' => Plugin::get_settings(),
            ]
        );
    }

    private function get_wp_roles(): array {
        $wp_roles = wp_roles();
        $roles    = [];

        foreach ( $wp_roles->get_names() as $slug => $label ) {
            $roles[] = [
                'slug'  => $slug,
                'label' => translate_user_role( $label ),
            ];
        }

        return $roles;
    }

    private function sanitize_role_abilities( array $input ): array {
        $wp_roles  = wp_roles()->get_names();
        $sanitized = [];

        foreach ( $input as $role => $config ) {
            $role = sanitize_key( $role );
            if ( ! isset( $wp_roles[ $role ] ) ) {
                continue;
            }

            $role_data = [
                'modules'   => isset( $config['modules'] ) && is_array( $config['modules'] )
                    ? array_values( array_map( 'sanitize_key', $config['modules'] ) )
                    : [],
                'abilities' => isset( $config['abilities'] ) && is_array( $config['abilities'] )
                    ? array_values( array_map( 'sanitize_text_field', $config['abilities'] ) )
                    : [],
            ];

            // Sanitize optional access_modes (Pro feature: T/R/P toggles).
            if ( isset( $config['access_modes'] ) && is_array( $config['access_modes'] ) ) {
                $role_data['access_modes'] = $this->sanitize_access_modes( $config['access_modes'] );
            }

            $sanitized[ $role ] = $role_data;
        }

        return $sanitized;
    }

    /**
     * Sanitize access_modes: {ability_id: {tools: bool, resources: bool, prompts: bool}}.
     */
    private function sanitize_access_modes( array $input ): array {
        $sanitized = [];

        foreach ( $input as $ability_id => $modes ) {
            $ability_id = sanitize_text_field( $ability_id );
            if ( ! is_array( $modes ) ) {
                continue;
            }

            $sanitized[ $ability_id ] = [
                'tools'     => ! empty( $modes['tools'] ),
                'resources' => ! empty( $modes['resources'] ),
                'prompts'   => ! empty( $modes['prompts'] ),
            ];
        }

        return $sanitized;
    }

    private function sanitize_role_workflows( array $input ): array {
        $wp_roles  = wp_roles()->get_names();
        $sanitized = [];

        foreach ( $input as $role => $workflow_ids ) {
            $role = sanitize_key( $role );
            if ( ! isset( $wp_roles[ $role ] ) ) {
                continue;
            }

            $sanitized[ $role ] = is_array( $workflow_ids )
                ? array_values( array_map( 'sanitize_text_field', $workflow_ids ) )
                : [];
        }

        return $sanitized;
    }

    /**
     * Return AI usage statistics from the awfah_ai_usage table.
     *
     * @param WP_REST_Request $request Request object with optional `from` and `to` params.
     * @return WP_REST_Response
     */
    public function get_usage_stats( WP_REST_Request $request ): WP_REST_Response {
        $from = $request->get_param( 'from' );
        $to   = $request->get_param( 'to' );

        // Default to last 30 days.
        if ( empty( $from ) ) {
            $from = gmdate( 'Y-m-d', strtotime( '-30 days' ) );
        }
        if ( empty( $to ) ) {
            $to = gmdate( 'Y-m-d' );
        }

        $by_tool = AI_Provider_Manager::get_usage_stats( $from, $to );

        // Also get daily breakdown for charts.
        $daily = self::get_daily_usage( $from, $to );

        // Compute totals.
        $total_requests          = 0;
        $total_prompt_tokens     = 0;
        $total_completion_tokens = 0;
        $total_total_tokens      = 0;

        foreach ( $by_tool as $row ) {
            $total_requests          += (int) $row['request_count'];
            $total_prompt_tokens     += (int) $row['total_prompt_tokens'];
            $total_completion_tokens += (int) $row['total_completion_tokens'];
            $total_total_tokens      += (int) $row['total_total_tokens'];
        }

        return new WP_REST_Response( [
            'from'    => $from,
            'to'      => $to,
            'totals'  => [
                'requests'          => $total_requests,
                'prompt_tokens'     => $total_prompt_tokens,
                'completion_tokens' => $total_completion_tokens,
                'total_tokens'      => $total_total_tokens,
            ],
            'by_tool' => $by_tool,
            'daily'   => $daily,
        ] );
    }

    /**
     * Get daily usage breakdown for chart display.
     *
     * @param string $from Start date (Y-m-d).
     * @param string $to   End date (Y-m-d).
     * @return array Daily usage data.
     */
    private static function get_daily_usage( string $from, string $to ): array {
        global $wpdb;
        $table = $wpdb->prefix . 'awfah_ai_usage';

        if ( $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ) !== $table ) {
            return [];
        }

        $results = $wpdb->get_results(
            $wpdb->prepare(
                "SELECT
                    DATE(created_at) as date,
                    COUNT(*) as request_count,
                    SUM(total_tokens) as total_tokens
                FROM {$table}
                WHERE created_at >= %s AND created_at < %s
                GROUP BY DATE(created_at)
                ORDER BY date ASC",
                $from . ' 00:00:00',
                $to . ' 23:59:59'
            ),
            ARRAY_A
        );

        return $results ?: [];
    }

    /**
     * Send a test error notification email.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response
     */
    public function send_test_error_email( WP_REST_Request $request ): WP_REST_Response {
        return new WP_REST_Response( Error_Email_Notifier::send_test_email() );
    }

    /**
     * Get the error log monitor status.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response
     */
    public function get_log_monitor_status( WP_REST_Request $request ): WP_REST_Response {
        return new WP_REST_Response( Error_Email_Notifier::get_log_monitor_status() );
    }

    /**
     * Rescan the error log immediately and send notifications for new errors.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response
     */
    public function rescan_error_log( WP_REST_Request $request ): WP_REST_Response {
        return new WP_REST_Response( Error_Email_Notifier::rescan_log() );
    }

    /**
     * Reset the error log scan position.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response
     */
    public function reset_error_log_position( WP_REST_Request $request ): WP_REST_Response {
        return new WP_REST_Response( Error_Email_Notifier::reset_log_position() );
    }

    /**
     * List all debug fixer backups (Pro feature, delegates via filter).
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error
     */
    public function get_backups( WP_REST_Request $request ) {
        if ( ! awfah_is_pro_active() ) {
            return new WP_Error( 'pro_required', sprintf( /* translators: %s: plugin brand name (do not translate) */ __( 'This feature requires %s.', 'ai-workflow-automation-ai-agent-hub' ), 'AtlasAI Connector Pro' ), [ 'status' => 403 ] );
        }
        $backups = apply_filters( 'awfah_backups_list', [] );
        return new WP_REST_Response( [ 'backups' => $backups ] );
    }

    /**
     * Delete a single backup by ID (Pro feature).
     *
     * @param WP_REST_Request $request Request object with 'id' param.
     * @return WP_REST_Response|WP_Error
     */
    public function delete_backup( WP_REST_Request $request ) {
        if ( ! awfah_is_pro_active() ) {
            return new WP_Error( 'pro_required', sprintf( /* translators: %s: plugin brand name (do not translate) */ __( 'This feature requires %s.', 'ai-workflow-automation-ai-agent-hub' ), 'AtlasAI Connector Pro' ), [ 'status' => 403 ] );
        }
        $id     = $request->get_param( 'id' );
        $result = apply_filters( 'awfah_backup_delete', [ 'success' => false ], $id );
        return new WP_REST_Response( $result );
    }

    /**
     * Delete all backups (Pro feature).
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error
     */
    public function delete_all_backups( WP_REST_Request $request ) {
        if ( ! awfah_is_pro_active() ) {
            return new WP_Error( 'pro_required', sprintf( /* translators: %s: plugin brand name (do not translate) */ __( 'This feature requires %s.', 'ai-workflow-automation-ai-agent-hub' ), 'AtlasAI Connector Pro' ), [ 'status' => 403 ] );
        }
        $result = apply_filters( 'awfah_backup_delete_all', [ 'success' => false ] );
        return new WP_REST_Response( $result );
    }

    /**
     * Restore a backup to its original location (Pro feature).
     *
     * @param WP_REST_Request $request Request object with 'id' param.
     * @return WP_REST_Response|WP_Error
     */
    public function restore_backup( WP_REST_Request $request ) {
        if ( ! awfah_is_pro_active() ) {
            return new WP_Error( 'pro_required', sprintf( /* translators: %s: plugin brand name (do not translate) */ __( 'This feature requires %s.', 'ai-workflow-automation-ai-agent-hub' ), 'AtlasAI Connector Pro' ), [ 'status' => 403 ] );
        }
        $id     = $request->get_param( 'id' );
        $result = apply_filters( 'awfah_backup_restore', new WP_Error( 'not_available', 'Backup restore not available.' ), $id );
        if ( is_wp_error( $result ) ) {
            return new WP_Error( $result->get_error_code(), $result->get_error_message(), [ 'status' => 400 ] );
        }
        return new WP_REST_Response( $result );
    }

    /**
     * Dismiss the Pro upsell notice for the current user.
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response
     */
    public function dismiss_pro_notice( WP_REST_Request $request ): WP_REST_Response {
        $user_id = get_current_user_id();
        update_user_meta( $user_id, 'awfah_pro_notice_dismissed', time() );

        return new WP_REST_Response( [ 'dismissed' => true ] );
    }

    /**
     * Return the saved global default AI preference (provider + model).
     */
    public function get_ai_preference( WP_REST_Request $request ): WP_REST_Response {
        return new WP_REST_Response( AI_Provider_Manager::get_default_preference() );
    }

    /**
     * Persist the global default AI preference (provider + model).
     */
    public function update_ai_preference( WP_REST_Request $request ): WP_REST_Response {
        $provider = (string) ( $request->get_param( 'provider' ) ?? 'auto' );
        $model    = (string) ( $request->get_param( 'model' ) ?? '' );

        if ( '' === $provider ) {
            $provider = 'auto';
        }

        AI_Provider_Manager::update_default_preference( $provider, $model );

        return new WP_REST_Response( AI_Provider_Manager::get_default_preference() );
    }

    // ── Phase 3: Error Groups ──────────────────────────────────────

    /**
     * Get tracked error groups.
     */
    public function get_error_groups( WP_REST_Request $request ): WP_REST_Response {
        $sort   = sanitize_key( $request->get_param( 'sort' ) ?: 'count' );
        $limit  = (int) ( $request->get_param( 'limit' ) ?: 50 );
        $tracker = Error_Tracker::instance();

        return new WP_REST_Response( [
            'groups'       => $tracker->get_groups( $sort, $limit ),
            'total_count'  => $tracker->get_total_count(),
            'group_count'  => count( $tracker->get_groups( 'count', 200 ) ),
        ] );
    }

    /**
     * Clear all tracked error groups.
     */
    public function clear_error_groups( WP_REST_Request $request ): WP_REST_Response {
        Error_Tracker::instance()->clear_groups();
        return new WP_REST_Response( [ 'cleared' => true ] );
    }

    // ── Phase 4: Error Trends ──────────────────────────────────────

    /**
     * Get error trend data (daily counts + weekly comparison).
     */
    public function get_error_trends( WP_REST_Request $request ): WP_REST_Response {
        $days    = (int) ( $request->get_param( 'days' ) ?: 7 );
        $tracker = Error_Tracker::instance();

        return new WP_REST_Response( [
            'daily_counts' => $tracker->get_daily_counts( min( $days, 30 ) ),
            'weekly_trend' => $tracker->get_weekly_trend(),
        ] );
    }

    // ── Phase 5: Auto-Fix ──────────────────────────────────────────

    /**
     * Execute an auto-fix via signed request.
     */
    public function execute_auto_fix( WP_REST_Request $request ): WP_REST_Response {
        $hash    = sanitize_text_field( $request->get_param( 'hash' ) ?? '' );
        $sig     = sanitize_text_field( $request->get_param( 'sig' ) ?? '' );
        $exp     = (int) ( $request->get_param( 'exp' ) ?? 0 );

        if ( '' === $hash || '' === $sig || 0 === $exp ) {
            return new WP_REST_Response( [ 'error' => 'Missing parameters.' ], 400 );
        }

        if ( time() > $exp ) {
            return new WP_REST_Response( [ 'error' => 'Link expired.' ], 403 );
        }

        $expected_sig = hash_hmac( 'sha256', $hash . $exp, wp_salt( 'nonce' ) );
        if ( ! hash_equals( $expected_sig, $sig ) ) {
            return new WP_REST_Response( [ 'error' => 'Invalid signature.' ], 403 );
        }

        // Rate limit: max 5 auto-fixes per hour.
        $rate_key   = 'awfah_auto_fix_count';
        $rate_count = (int) get_transient( $rate_key );
        if ( $rate_count >= 5 ) {
            return new WP_REST_Response( [ 'error' => 'Rate limit exceeded. Max 5 auto-fixes per hour.' ], 429 );
        }

        /**
         * Execute the auto-fix. Pro plugin hooks into this filter.
         *
         * @param array|null $result  Default null (no fix applied).
         * @param string     $hash    Error hash.
         * @return array|null Fix result or null if no handler.
         */
        $result = apply_filters( 'awfah_auto_fix_execute', null, $hash );

        if ( null === $result ) {
            return new WP_REST_Response( [ 'error' => 'No auto-fix handler available. Pro plugin required.' ], 400 );
        }

        set_transient( $rate_key, $rate_count + 1, HOUR_IN_SECONDS );

        return new WP_REST_Response( $result );
    }

    // ── Phase 6: Test Webhook ──────────────────────────────────────

    /**
     * Send a test webhook notification.
     */
    public function send_test_webhook( WP_REST_Request $request ): WP_REST_Response {
        $settings = Error_Email_Notifier::get_notification_settings();

        if ( empty( $settings['webhook_url'] ) ) {
            return new WP_REST_Response( [ 'error' => 'No webhook URL configured.' ], 400 );
        }

        $test_error = [
            'severity'    => 'warning',
            'message'     => 'This is a test webhook notification from AtlasAI Connector.',
            'file'        => '/wp-content/plugins/example/test.php',
            'line'        => 42,
            'source_type' => 'plugin',
            'source_name' => 'example-plugin',
            'timestamp'   => current_time( 'mysql' ),
        ];

        /**
         * Dispatch a test webhook. Pro plugin hooks into this filter.
         *
         * @param bool  $sent    Whether the webhook was sent.
         * @param array $errors  Array of error data.
         * @param array $settings Notification settings.
         * @return bool
         */
        $sent = apply_filters( 'awfah_error_webhook_dispatch', false, [ $test_error ], $settings );

        if ( $sent ) {
            return new WP_REST_Response( [ 'sent' => true, 'message' => 'Test webhook sent successfully.' ] );
        }

        return new WP_REST_Response( [ 'error' => 'Webhook dispatch failed. Pro plugin required for webhook support.' ], 400 );
    }
}
