<?php

namespace AIPT\Api\BulkGenerator\FAQ;

use WP_Error;
use WP_REST_Request;
use WP_REST_Response;

class FAQGeneratorController {
    use \AIPT\Api\Traits\RateLimitTrait;

    /**
     * @var FAQGeneratorService
     */
    private $service;

    public function __construct() {
        $this->service = new FAQGeneratorService();
    }

    public function register_routes(): void {
        register_rest_route(
            'aipt/v1',
            '/faq-generator/bulk-generate',
            [
                'methods' => 'POST',
                'callback' => [$this, 'bulk_generate'],
                'permission_callback' => [$this, 'check_permissions'],
                'args' => [
                    'productIds' => [
                        'type' => 'array',
                        'required' => true,
                    ],
                    'options' => [
                        'type' => 'object',
                        'required' => false,
                    ],
                ],
            ]
        );

        register_rest_route(
            'aipt/v1',
            '/faq-generator/bulk-apply',
            [
                'methods' => 'POST',
                'callback' => [$this, 'bulk_apply'],
                'permission_callback' => [$this, 'check_permissions'],
                'args' => [
                    'results' => [
                        'type' => 'array',
                        'required' => true,
                    ],
                    'options' => [
                        'type' => 'object',
                        'required' => false,
                    ],
                ],
            ]
        );

        register_rest_route(
            'aipt/v1',
            '/faq-generator/bulk-reject',
            [
                'methods' => 'POST',
                'callback' => [$this, 'bulk_reject'],
                'permission_callback' => [$this, 'check_permissions'],
                'args' => [
                    'productIds' => [
                        'type' => 'array',
                        'required' => true,
                    ],
                ],
            ]
        );
    }

    public function check_permissions(): bool {
        return current_user_can('manage_woocommerce');
    }

    /**
     * Apply free-plan defaults to FAQ options.
     *
     * Overrides premium-only fields with free defaults, then exposes
     * the result via a filter so the Premium module can restore the
     * original values when a valid licence is present.
     *
     * @since 2.6.0
     *
     * @param array $options Raw request options.
     * @return array Options with free defaults applied (or premium values restored via filter).
     */
    private function applyFreeDefaults( array $options ): array {
        $free_defaults = array(
            'faqMode'     => 'both',
            'writeMode'   => 'append',
            'targetField' => 'post_content',
            'faqSources'  => array( 'product_description' ),
        );

        $controlled = array_merge( $options, $free_defaults );

        /**
         * Filter FAQ generator validated options.
         *
         * Premium module can hook here to restore premium option values
         * when a valid license is present.
         *
         * @since 2.6.0
         *
         * @param array $controlled Options with free defaults applied.
         * @param array $options    Original request options.
         */
        return apply_filters( 'aipt_faq_validate_options', $controlled, $options );
    }

    public function bulk_generate(WP_REST_Request $request) {
        $rate_check = $this->checkRateLimit((int) get_current_user_id(), 'faq');
        if (!$rate_check['allowed']) { return $this->rateLimitResponse($rate_check); }

        $product_ids = $request->get_param('productIds');
        $options = $request->get_param('options');

        if (!is_array($product_ids) || empty($product_ids)) {
            return new WP_Error(
                'aipt_faq_invalid_products',
                __('Please select at least one product to generate FAQs.', 'ai-product-tools'),
                ['status' => 400]
            );
        }

        if (!is_array($options)) {
            $options = [];
        }

        $options = $this->applyFreeDefaults( $options );

        try {
            $results = $this->service->bulk_generate($product_ids, $options);

            return new WP_REST_Response(
                [
                    'success' => true,
                    'message' => __('FAQ generation completed.', 'ai-product-tools'),
                    'results' => $results,
                ],
                200
            );
        } catch (\Exception $exception) {
            return new WP_Error(
                'aipt_faq_generation_failed',
                $exception->getMessage(),
                ['status' => 500]
            );
        }
    }

    public function bulk_apply(WP_REST_Request $request) {
        $payloads = $request->get_param('results');

        if (!is_array($payloads) || empty($payloads)) {
            return new WP_Error(
                'aipt_faq_invalid_results',
                __('No FAQ results were provided for applying content.', 'ai-product-tools'),
                ['status' => 400]
            );
        }

        $apply_options = $request->get_param('options');
        if (!is_array($apply_options)) {
            $apply_options = [];
        }

        $apply_options = $this->applyFreeDefaults( $apply_options );

        $applied   = 0;
        $failed    = 0;
        $responses = [];

        foreach ($payloads as $result) {
            if (!is_array($result)) {
                continue;
            }

            $product_id = isset($result['product_id']) ? absint($result['product_id']) : 0;
            if ($product_id <= 0) {
                $failed++;
                $responses[] = [
                    'product_id' => 0,
                    'status'     => 'error',
                    'message'    => __('Invalid product identifier.', 'ai-product-tools'),
                ];
                continue;
            }

            $product = wc_get_product($product_id);
            if (!$product) {
                $failed++;
                $responses[] = [
                    'product_id' => $product_id,
                    'status'     => 'error',
                    'message'    => __('Product could not be loaded.', 'ai-product-tools'),
                ];
                continue;
            }

            try {
                $write_mode = isset($result['writeMode']) && is_string($result['writeMode'])
                    ? strtolower($result['writeMode'])
                    : (isset($apply_options['writeMode']) ? strtolower((string) $apply_options['writeMode']) : 'replace');

                $write_mode = in_array($write_mode, ['append', 'replace'], true) ? $write_mode : 'replace';

                if (empty($result['faqs']) || !is_array($result['faqs'])) {
                    $failed++;
                    $responses[] = [
                        'product_id' => $product_id,
                        'status'     => 'error',
                        'message'    => __('No FAQ items provided.', 'ai-product-tools'),
                    ];
                    continue;
                }

                $structured_faqs = [];
                foreach ($result['faqs'] as $faq) {
                    if (is_array($faq) && isset($faq['question'], $faq['answer'])) {
                        $structured_faqs[] = [
                            'question' => sanitize_text_field((string) $faq['question']),
                            'answer'   => wp_kses_post((string) $faq['answer']),
                        ];
                    }
                }

                if (empty($structured_faqs)) {
                    $failed++;
                    $responses[] = [
                        'product_id' => $product_id,
                        'status'     => 'error',
                        'message'    => __('FAQ items could not be validated.', 'ai-product-tools'),
                    ];
                    continue;
                }

                if ('append' === $write_mode) {
                    $existing_json = get_post_meta($product_id, '_aipt_faq_data', true);
                    $existing_faqs = !empty($existing_json) ? json_decode($existing_json, true) : [];
                    if (is_array($existing_faqs)) {
                        $structured_faqs = array_merge($existing_faqs, $structured_faqs);
                    }
                }

                $json_to_save = wp_json_encode($structured_faqs);
                if (false === $json_to_save) {
                    $failed++;
                    $responses[] = [
                        'product_id' => $product_id,
                        'status'     => 'error',
                        'message'    => __('Failed to encode FAQ data.', 'ai-product-tools'),
                    ];
                    continue;
                }

                update_post_meta($product_id, '_aipt_faq_data', $json_to_save);

                $applied++;
                $responses[] = [
                    'product_id' => $product_id,
                    'status'     => 'success',
                    'message'    => __('FAQ content applied successfully.', 'ai-product-tools'),
                ];
            } catch (\Exception $exception) {
                $failed++;
                $responses[] = [
                    'product_id' => $product_id,
                    'status'     => 'error',
                    'message'    => $exception->getMessage(),
                ];
            }
        }

        return new WP_REST_Response(
            [
                'success'       => $failed === 0,
                'applied_count' => $applied,
                'failed_count'  => $failed,
                'results'       => $responses,
            ],
            200
        );
    }

    public function bulk_reject(WP_REST_Request $request) {
        $product_ids = $request->get_param('productIds');

        if (!is_array($product_ids)) {
            return new WP_Error(
                'aipt_faq_invalid_reject_payload',
                __('A valid product list is required to reject FAQ results.', 'ai-product-tools'),
                ['status' => 400]
            );
        }

        $total = count($product_ids);

        return new WP_REST_Response(
            [
                'success' => true,
                'rejectedCount' => $total,
                'message' => sprintf(
                    /* translators: %d: rejected product count */
                    __('Rejected FAQ results for %d products.', 'ai-product-tools'),
                    $total
                ),
            ],
            200
        );
    }

    /**
     * Register _aipt_faq_data post meta for REST exposure.
     *
     * Called from Init::register_hooks() so the meta is available in the REST API.
     */
    public static function register_meta(): void {
        register_post_meta('product', '_aipt_faq_data', [
            'type'              => 'string',
            'description'       => 'Structured FAQ data for accordion rendering',
            'single'            => true,
            'show_in_rest'      => true,
            'sanitize_callback' => [ __CLASS__, 'sanitize_faq_json' ],
            'auth_callback'     => function() {
                return current_user_can('manage_woocommerce');
            },
        ]);
    }

    /**
     * Sanitize FAQ JSON meta value.
     *
     * Validates JSON structure (array of question/answer pairs).
     * Returns the original JSON string only if valid, empty string otherwise.
     *
     * @param string $value Raw meta value.
     * @return string Sanitized JSON string or empty string.
     */
    public static function sanitize_faq_json( $value ): string {
        if ( ! is_string( $value ) || '' === $value ) {
            return '';
        }

        $decoded = json_decode( $value, true );

        if ( ! is_array( $decoded ) ) {
            return '';
        }

        $sanitized = [];
        foreach ( $decoded as $faq ) {
            if ( ! is_array( $faq ) || ! isset( $faq['question'], $faq['answer'] ) ) {
                continue;
            }
            $sanitized[] = [
                'question' => sanitize_text_field( (string) $faq['question'] ),
                'answer'   => wp_kses_post( (string) $faq['answer'] ),
            ];
        }

        if ( empty( $sanitized ) ) {
            return '';
        }

        $json = wp_json_encode( $sanitized );

        return is_string( $json ) ? $json : '';
}
}
