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

class FORMFORGE_Rest_Api {
    private static $instance = null;
    public static function instance() { if (!self::$instance) self::$instance = new self(); return self::$instance; }

    private function __construct() {
        add_action('rest_api_init', [$this, 'register']);
    }

    public function register() {
        $ns = 'formforge/v1';
        $admin = function () { return current_user_can('manage_options'); };
        $public = '__return_true';

        register_rest_route($ns, '/forms', [
            ['methods' => 'GET', 'callback' => [$this, 'list_forms'], 'permission_callback' => $admin],
            ['methods' => 'POST', 'callback' => [$this, 'create_form'], 'permission_callback' => $admin],
        ]);
        register_rest_route($ns, '/forms/(?P<id>\d+)', [
            ['methods' => 'GET', 'callback' => [$this, 'get_form'], 'permission_callback' => $admin],
            ['methods' => 'PUT', 'callback' => [$this, 'update_form'], 'permission_callback' => $admin],
            ['methods' => 'DELETE', 'callback' => [$this, 'delete_form'], 'permission_callback' => $admin],
        ]);
        register_rest_route($ns, '/forms/(?P<id>\d+)/submit', [
            'methods' => 'POST', 'callback' => [$this, 'submit_form'], 'permission_callback' => $public,
        ]);
        register_rest_route($ns, '/submissions/(?P<form_id>\d+)', [
            'methods' => 'GET', 'callback' => [$this, 'get_submissions'], 'permission_callback' => $admin,
        ]);
        register_rest_route($ns, '/analytics/(?P<form_id>\d+)', [
            'methods' => 'GET', 'callback' => [$this, 'get_analytics'], 'permission_callback' => $admin,
        ]);
        register_rest_route($ns, '/generate', [
            'methods' => 'POST', 'callback' => [$this, 'ai_generate'], 'permission_callback' => $admin,
        ]);
        register_rest_route($ns, '/templates', [
            'methods' => 'GET', 'callback' => [$this, 'list_templates'], 'permission_callback' => $public,
        ]);
        register_rest_route($ns, '/templates/categories', [
            'methods' => 'GET', 'callback' => [$this, 'list_template_categories'], 'permission_callback' => $public,
        ]);
    }

    public function list_templates($r) {
        $cat = $r->get_param('category');
        $templates = $cat ? FORMFORGE_Templates::get_by_category($cat) : FORMFORGE_Templates::get_all();
        $result = [];
        foreach ($templates as $key => $tpl) {
            $result[] = [
                'key'         => $key,
                'title'       => $tpl['title'],
                'description' => $tpl['description'],
                'icon'        => $tpl['icon'],
                'category'    => $tpl['category'],
                'field_count' => count($tpl['fields']),
            ];
        }
        return rest_ensure_response($result);
    }

    public function list_template_categories() {
        return rest_ensure_response(array_values(FORMFORGE_Templates::get_categories()));
    }

    public function list_forms() { return rest_ensure_response(FORMFORGE_Form_Builder::instance()->get_all()); }

    public function get_form($r) { return rest_ensure_response(FORMFORGE_Form_Builder::instance()->get((int) $r['id'])); }

    public function create_form($r) {
        $builder = FORMFORGE_Form_Builder::instance();
        if (!FORMFORGE_License::instance()->can('unlimited_forms')) {
            $count = count($builder->get_all_unfiltered());
            if (!FORMFORGE_License::instance()->check_limit('forms', $count)) {
                return new WP_Error('pro_only', __('Form creation is unavailable for the current plan.', 'formforge'), ['status' => 403]);
            }
        }

        $id = $builder->create($r->get_json_params());
        return rest_ensure_response(['id' => $id]);
    }

    public function update_form($r) {
        FORMFORGE_Form_Builder::instance()->update((int) $r['id'], $r->get_json_params());
        return rest_ensure_response(['success' => true]);
    }

    public function delete_form($r) {
        FORMFORGE_Form_Builder::instance()->delete((int) $r['id']);
        return rest_ensure_response(['success' => true]);
    }

    public function submit_form($r) {
        // #22: there is no safe tokenless public REST submission path, and the
        // old stub returned a misleading 200. The real submission flow
        // (FORMFORGE_Form_Handler::handle_submit, AJAX action
        // "formforge_submit" / nopriv) enforces a WP nonce + structural
        // anti-spam (honeypot, timing, HMAC token), payment intents, and file
        // uploads — none of which a JSON REST POST can satisfy. Fail loudly
        // (501) and point callers at the supported path instead of silently
        // accepting nothing. The GET /forms/{id} route still serves the form
        // definition for headless rendering.
        return new WP_Error(
            'rest_submit_unsupported',
            __('Direct REST submission is not supported. Render the form headless via GET /formforge/v1/forms/{id}, but submit through the [formforge] shortcode, which posts to the AJAX endpoint (action "formforge_submit") with a nonce and full anti-spam protection.', 'formforge'),
            ['status' => 501]
        );
    }

    public function get_submissions($r) {
        global $wpdb;
        $subs = $wpdb->get_results($wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- custom plugin table; direct query is intended.
            "SELECT * FROM {$wpdb->prefix}formforge_submissions WHERE form_id = %d ORDER BY created_at DESC LIMIT 100",
            (int) $r['form_id']
        ));
        foreach ($subs as &$s) $s->data = json_decode($s->data, true);
        return rest_ensure_response($subs);
    }

    public function get_analytics($r) {
        if (!FORMFORGE_License::instance()->can('analytics')) {
            return new WP_Error('pro_only', __('Analytics requires Pro plan.', 'formforge'), ['status' => 403]);
        }
        // Belt-and-suspenders: License::can already returns false when the
        // Pro add-on isn't installed (bridge has no features registered).
        // This guard catches edge cases where stale license options grant
        // access without the implementation class being present.
        if (!class_exists('FORMFORGE_Analytics')) {
            return new WP_Error('feature_not_available', __('Analytics requires the Form Forge Pro add-on.', 'formforge'), ['status' => 404]);
        }
        return rest_ensure_response(FORMFORGE_Analytics::instance()->get_stats((int) $r['form_id']));
    }

    public function ai_generate($r) {
        if (!FORMFORGE_License::instance()->can('ai_generation')) {
            return new WP_Error('pro_only', __('AI Form Generation requires Pro plan.', 'formforge'), ['status' => 403]);
        }
        if (!class_exists('FORMFORGE_AI_Client')) {
            return new WP_Error('feature_not_available', __('AI Form Generation requires the Form Forge Pro add-on.', 'formforge'), ['status' => 404]);
        }

        $prompt = $r->get_param('prompt');
        if (empty($prompt)) {
            return new WP_Error('empty_prompt', __('Please describe the form you want to create.', 'formforge'), ['status' => 400]);
        }

        $ai = FORMFORGE_AI_Client::instance();
        if (!$ai->is_configured()) {
            return rest_ensure_response([
                'fields'  => [],
                'message' => __('AI not configured. Go to Form Forge → Settings and enter your API key.', 'formforge'),
            ]);
        }

        $result = $ai->generate_form($prompt);

        if (is_wp_error($result)) {
            if ($result->get_error_code() === 'credits_exhausted') {
                $data = $result->get_error_data();
                return rest_ensure_response([
                    'fields'     => [],
                    'success'    => false,
                    'error'      => 'credits_exhausted',
                    'message'    => $result->get_error_message(),
                    'remaining'  => $data['remaining'] ?? 0,
                    'reset_date' => $data['reset_date'] ?? '',
                ]);
            }
            return rest_ensure_response([
                'fields'  => [],
                'message' => $result->get_error_message(),
            ]);
        }

        $form_settings = $ai->get_last_form_settings();
        $payload = [
            'fields'  => $result,
            /* translators: %d: number of fields generated */
            'message' => sprintf(__('Generated %d fields.', 'formforge'), count($result)),
        ];
        if (!empty($form_settings)) {
            $payload['settings'] = $form_settings;
        }
        return rest_ensure_response($payload);
    }
}
