<?php

/**
 * Feedback REST API Controller
 *
 * Handles feedback submission via REST API.
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   0.1.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

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




class FeedbackController extends BaseController {
    /**
     * Constructor
     */
    public function __construct() {
        $this->rest_base = 'feedback';
    }

    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Simple feedback (positive/negative)
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            [
                [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [$this, 'submit_feedback'],
                    'permission_callback' => [$this, 'submit_feedback_permissions_check'],
                    'args'                => $this->get_feedback_schema(),
                ],
            ]
        );
        
        // Comprehensive feedback submission
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/submit',
            [
                [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [$this, 'submit_comprehensive_feedback'],
                    'permission_callback' => [$this, 'submit_feedback_permissions_check'],
                    'args'                => $this->get_comprehensive_feedback_schema(),
                ],
            ]
        );
        
        // Get feedback list
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/list',
            [
                [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [$this, 'get_feedback_list'],
                    'permission_callback' => [$this, 'submit_feedback_permissions_check'],
                    'args'                => [
                        'type' => [
                            'description' => __('Filter by feedback type', 'prorank-seo'),
                            'type'        => 'string',
                            'enum'        => ['all', 'feature', 'bug', 'general', 'support'],
                            'default'     => 'all',
                        ],
                        'limit' => [
                            'description' => __('Number of items to return', 'prorank-seo'),
                            'type'        => 'integer',
                            'default'     => 10,
                            'minimum'     => 1,
                            'maximum'     => 100,
                        ],
                    ],
                ],
            ]
        );
    }

    /**
     * Check permissions for submitting feedback
     *
     * @param WP_REST_Request $request Request object.
     * @return bool|WP_Error
     */
    public function submit_feedback_permissions_check(WP_REST_Request $request) {
        if (!current_user_can('read')) {
            return new WP_Error(
                'rest_forbidden',
                __('You do not have permission to submit feedback.', 'prorank-seo'),
                ['status' => 403]
            );
        }

        return true;
    }

    /**
     * Submit feedback
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error
     */
    public function submit_feedback(WP_REST_Request $request) {
        return $this->try_callback(function() use ($request) {
            $type = $request->get_param('type');
            $screen_id = $request->get_param('screen_id');

            // Log feedback (placeholder for Phase 0)
            prorank_log(sprintf(
                '[ProRank SEO Feedback] Type: %s, Screen: %s, User: %d',
                $type,
                $screen_id,
                get_current_user_id()
            ));

            return $this->get_success_response(
                ['submitted' => true],
                __('Thank you for your feedback!', 'prorank-seo')
            );
        });
    }

    /**
     * Submit comprehensive feedback
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error
     */
    public function submit_comprehensive_feedback(WP_REST_Request $request) {
        return $this->try_callback(function() use ($request) {
            $type = $request->get_param('type');
            $subject = $request->get_param('subject');
            $message = $request->get_param('message');
            $priority = $request->get_param('priority');
            $email = $request->get_param('email');
            
            // Get current user info
            $current_user = wp_get_current_user();
            $user_email = $email ?: $current_user->user_email;
            $user_name = $current_user->display_name ?: __('Anonymous', 'prorank-seo');
            
            // Get canonical license key (LicenseManager first, legacy options fallback)
            $license_key = $this->resolve_license_key();
            
            // Prepare feedback data
            $feedback_data = [
                'type' => $type,
                'subject' => $subject,
                'message' => $message,
                'priority' => $priority,
                'email' => $user_email,
                'name' => $user_name,
                'site_url' => get_site_url(),
                'license_key' => $license_key,
                'system_info' => $this->get_system_info(),
                'submitted_at' => current_time('mysql'),
            ];
            
            $sent = $this->send_feedback_to_server($feedback_data);
            if (!$sent) {
                $this->store_comprehensive_feedback($feedback_data);
            }

            return $this->get_success_response(
                [
                    'success' => true,
                    'synced' => $sent,
                ],
                $sent
                    ? __('Thank you for your feedback! We\'ll review it soon.', 'prorank-seo')
                    : __('Thank you for your feedback! It has been saved and will be synced when connection is available.', 'prorank-seo')
            );
        });
    }
    
    /**
     * Get feedback list
     *
     * @param WP_REST_Request $request Request object.
     * @return WP_REST_Response|WP_Error
     */
    public function get_feedback_list(WP_REST_Request $request) {
        return $this->try_callback(function() use ($request) {
            $type = $request->get_param('type');
            $limit = $request->get_param('limit');
            $local_feedback = $this->get_local_feedback_queue((string) $type, (int) $limit);
            $license_key = $this->resolve_license_key();
            $site_url = untrailingslashit((string) get_site_url());
            
            // Try to fetch from server first
            $endpoint = defined('PRORANK_FEEDBACK_ENDPOINT')
                ? PRORANK_FEEDBACK_ENDPOINT
                : 'https://prorank.io/api/v1/feedback';
            $query_args = [
                'type' => $type,
                'limit' => $limit,
                'site_url' => $site_url,
            ];

            if ($license_key !== '') {
                $query_args['license_key'] = $license_key;
            }

            $endpoint .= '?' . http_build_query($query_args);
            
            $response = wp_remote_get($endpoint, [
                'timeout' => 10,
            ]);
            
            if (!is_wp_error($response)) {
                $response_code = wp_remote_retrieve_response_code($response);
                if ($response_code === 200) {
                    $body = wp_remote_retrieve_body($response);
                    $data = json_decode($body, true);
                    
                    if ($data && isset($data['success']) && $data['success']) {
                        $remote_feedback = is_array($data['data'] ?? null) ? $data['data'] : [];
                        $feedback = $this->merge_feedback_items($remote_feedback, $local_feedback, (int) $limit);

                        return $this->get_success_response([
                            'feedback' => $feedback,
                            'stats' => $data['stats'] ?? [],
                            'source' => empty($local_feedback) ? 'remote' : 'remote+local',
                        ]);
                    }
                }
            }
            
            // Fallback to local data if server is unavailable
            return $this->get_success_response([
                'feedback' => $local_feedback,
                'stats' => [],
                'source' => 'local',
            ]);
        });
    }

    /**
     * Get locally stored feedback queue items filtered and sorted for display.
     */
    private function get_local_feedback_queue(string $type, int $limit): array {
        $feedback_queue = get_option('prorank_feedback_queue', []);
        if (!is_array($feedback_queue)) {
            return [];
        }

        if ($type && $type !== 'all') {
            $feedback_queue = array_filter($feedback_queue, function($item) use ($type) {
                return is_array($item) && (($item['type'] ?? '') === $type);
            });
        }

        usort($feedback_queue, function($a, $b) {
            $time_a = is_array($a) ? ($a['submitted_at'] ?? $a['timestamp'] ?? '1970-01-01 00:00:00') : '1970-01-01 00:00:00';
            $time_b = is_array($b) ? ($b['submitted_at'] ?? $b['timestamp'] ?? '1970-01-01 00:00:00') : '1970-01-01 00:00:00';
            return strtotime((string) $time_b) - strtotime((string) $time_a);
        });

        return array_values(array_slice($feedback_queue, 0, $limit));
    }

    /**
     * Merge remote and locally queued feedback without duplicating identical ids.
     */
    private function merge_feedback_items(array $remote_feedback, array $local_feedback, int $limit): array {
        $merged = [];
        $seen_ids = [];

        foreach ([$local_feedback, $remote_feedback] as $bucket) {
            foreach ($bucket as $item) {
                if (!is_array($item)) {
                    continue;
                }

                $feedback_id = (string) ($item['id'] ?? '');
                if ($feedback_id !== '' && isset($seen_ids[$feedback_id])) {
                    continue;
                }

                if ($feedback_id !== '') {
                    $seen_ids[$feedback_id] = true;
                }

                $merged[] = $item;
            }
        }

        usort($merged, function($a, $b) {
            $time_a = is_array($a) ? ($a['submitted_at'] ?? $a['timestamp'] ?? '1970-01-01 00:00:00') : '1970-01-01 00:00:00';
            $time_b = is_array($b) ? ($b['submitted_at'] ?? $b['timestamp'] ?? '1970-01-01 00:00:00') : '1970-01-01 00:00:00';
            return strtotime((string) $time_b) - strtotime((string) $time_a);
        });

        return array_values(array_slice($merged, 0, $limit));
    }
    
    /**
     * Send feedback to webapp server
     *
     * @param array $feedback_data Feedback data
     * @return bool Success status
     */
    private function send_feedback_to_server(array $feedback_data): bool {
        if (!defined('PRORANK_FEEDBACK_ENDPOINT') || empty(PRORANK_FEEDBACK_ENDPOINT)) {
            return false;
        }

        $response = wp_remote_post(PRORANK_FEEDBACK_ENDPOINT, [
            'timeout' => 15,
            'headers' => [
                'Content-Type' => 'application/json',
                'X-ProRank-Plugin-Version' => defined('PRORANK_SEO_VERSION') ? PRORANK_SEO_VERSION : 'unknown',
            ],
            'body' => wp_json_encode($feedback_data),
        ]);

        if (is_wp_error($response)) {
            prorank_log('[ProRank SEO] Failed to send feedback to server: ' . $response->get_error_message());
            return false;
        }

        $response_code = wp_remote_retrieve_response_code($response);
        if ($response_code < 200 || $response_code >= 300) {
            prorank_log('[ProRank SEO] Server returned error code: ' . $response_code);
            return false;
        }

        $body = json_decode(wp_remote_retrieve_body($response), true);
        return is_array($body) && !empty($body['success']);
    }
    
    /**
     * Store comprehensive feedback
     *
     * @param array $feedback_data Feedback data
     * @return bool Success status
     */
    private function store_comprehensive_feedback(array $feedback_data): bool {
        $feedback_queue = get_option('prorank_feedback_queue', []);
        
        // Add unique ID
        $feedback_data['id'] = wp_generate_uuid4();
        if (empty($feedback_data['submitted_at'])) {
            $feedback_data['submitted_at'] = current_time('mysql');
        }
        if (empty($feedback_data['timestamp'])) {
            $feedback_data['timestamp'] = $feedback_data['submitted_at'];
        }
        
        // Add to queue
        $feedback_queue[] = $feedback_data;
        
        // Keep only last 100 items
        if (count($feedback_queue) > 100) {
            $feedback_queue = array_slice($feedback_queue, -100);
        }
        
        return update_option('prorank_feedback_queue', $feedback_queue);
    }

    /**
     * Get basic system information for feedback payloads.
     *
     * @return array
     */
    private function get_system_info(): array {
        $theme = wp_get_theme();

        return [
            'php_version' => PHP_VERSION,
            'wp_version' => get_bloginfo('version'),
            'plugin_version' => defined('PRORANK_SEO_VERSION') ? PRORANK_SEO_VERSION : '',
            'active_theme' => $theme ? $theme->get('Name') : '',
            'theme_version' => $theme ? $theme->get('Version') : '',
            'is_multisite' => is_multisite(),
            'memory_limit' => ini_get('memory_limit'),
        ];
    }

    /**
     * Resolve current license key from canonical storage.
     *
     * @return string
     */
    private function resolve_license_key(): string {
        // Preferred path: LicenseManager (handles encrypted storage + migrations).
        if (function_exists('prorank')) {
            try {
                $plugin = prorank();
                if ($plugin && method_exists($plugin, 'license')) {
                    $license_manager = $plugin->license();
                    if ($license_manager && method_exists($license_manager, 'get_license_key')) {
                        $key = trim((string) $license_manager->get_license_key());
                        if ($key !== '') {
                            return $key;
                        }
                    }
                }
            } catch (\Throwable $e) {
                // Continue to legacy fallbacks below.
            }
        }

        // Legacy fallback keys (for older installs).
        $key = trim((string) get_option('prorank_seo_license_key', ''));
        if ($key !== '') {
            return $key;
        }

        return trim((string) get_option('prorank_license_key', ''));
    }

    /**
     * Get feedback schema
     *
     * @return array
     */
    private function get_feedback_schema(): array {
        return [
            'type' => [
                'description'       => __('Feedback type (positive or negative).', 'prorank-seo'),
                'type'              => 'string',
                'enum'              => ['positive', 'negative'],
                'required'          => true,
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'screen_id' => [
                'description'       => __('Current admin screen ID.', 'prorank-seo'),
                'type'              => 'string',
                'required'          => true,
                'sanitize_callback' => 'sanitize_text_field',
            ],
        ];
    }
    
    /**
     * Get comprehensive feedback schema
     *
     * @return array
     */
    private function get_comprehensive_feedback_schema(): array {
        return [
            'type' => [
                'description'       => __('Type of feedback', 'prorank-seo'),
                'type'              => 'string',
                'enum'              => ['feature', 'bug', 'general', 'support'],
                'required'          => true,
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'subject' => [
                'description'       => __('Feedback subject', 'prorank-seo'),
                'type'              => 'string',
                'required'          => true,
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'message' => [
                'description'       => __('Feedback message', 'prorank-seo'),
                'type'              => 'string',
                'required'          => true,
                'sanitize_callback' => 'sanitize_textarea_field',
            ],
            'priority' => [
                'description'       => __('Priority level', 'prorank-seo'),
                'type'              => 'string',
                'enum'              => ['low', 'medium', 'high'],
                'default'           => 'medium',
                'sanitize_callback' => 'sanitize_text_field',
            ],
            'email' => [
                'description'       => __('Contact email', 'prorank-seo'),
                'type'              => 'string',
                'format'            => 'email',
                'sanitize_callback' => 'sanitize_email',
            ],
        ];
    }
}
