<?php
/**
 * REST API Import Controller.
 *
 * Handles listing available importers, previewing, and executing settings imports.
 *
 * @package NimblyMail\SMTP
 *
 * @since 1.0.0
 */

namespace NimblyMail\SMTP\Rest;

use NimblyMail\SMTP\Import\ImporterRegistry;
use WP_REST_Server;
use WP_REST_Response;
use WP_REST_Request;
use WP_Error;

defined( 'ABSPATH' ) || exit;

/**
 * Class ImportController
 *
 * Exposes REST endpoints to list, preview, and execute settings imports
 * from third-party email plugins.
 *
 * @since 1.0.0
 */
class ImportController extends AbstractController {

    /**
     * Register REST routes for the import feature.
     *
     * Registers three routes:
     * - GET  /import/available         — list all importers with availability.
     * - GET  /import/preview/<source>  — preview settings for a given importer.
     * - POST /import/<source>          — execute the import for a given importer.
     *
     * @since 1.0.0
     */
    public function register_routes(): void {
        register_rest_route(
            self::NAMESPACE,
            '/import/available',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_available' ),
                    'permission_callback' => array( $this, 'permissions_check' ),
                ),
            )
        );

        $source_args = array(
            'source' => array(
                'type'              => 'string',
                'sanitize_callback' => 'sanitize_text_field',
                'validate_callback' => function ( string $source ): bool {
                    return null !== ImporterRegistry::init()->get_importer( $source );
                },
            ),
        );

        register_rest_route(
            self::NAMESPACE,
            '/import/preview/(?P<source>[a-z0-9-]+)',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'preview' ),
                    'permission_callback' => array( $this, 'permissions_check' ),
                    'args'                => $source_args,
                ),
            )
        );

        register_rest_route(
            self::NAMESPACE,
            '/import/(?P<source>[a-z0-9-]+)',
            array(
                array(
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => array( $this, 'execute_import' ),
                    'permission_callback' => array( $this, 'permissions_check' ),
                    'args'                => $source_args,
                ),
            )
        );
    }

    /**
     * Return all registered importers with their availability status.
     *
     * @since 1.0.0
     *
     * @return WP_REST_Response
     */
    public function get_available(): WP_REST_Response {
        $importers = array();

        foreach ( ImporterRegistry::init()->get_importers() as $importer ) {
            $importers[] = array(
                'slug'        => $importer->get_slug(),
                'name'        => $importer->get_name(),
                'description' => $importer->get_description(),
                'available'   => $importer->is_available(),
            );
        }

        return new WP_REST_Response( array( 'importers' => $importers ) );
    }

    /**
     * Preview the settings that would be imported from the given source.
     *
     * Returns a 404 if the importer is not registered or has no data available.
     *
     * @since 1.0.0
     *
     * @param WP_REST_Request $request The request object.
     *
     * @return WP_REST_Response|WP_Error
     */
    public function preview( WP_REST_Request $request ) {
        $source   = $request->get_param( 'source' );
        $importer = ImporterRegistry::init()->get_importer( $source );

        if ( null === $importer || ! $importer->is_available() ) {
            return new WP_Error(
                'importer_not_found',
                __( 'The requested importer is not available.', 'nimblymail-smtp' ),
                array( 'status' => 404 )
            );
        }

        return new WP_REST_Response(
            array(
                'source'  => $importer->get_slug(),
                'name'    => $importer->get_name(),
                'preview' => $importer->preview(),
            )
        );
    }

    /**
     * Execute the settings import for the given source.
     *
     * Enforces a rate limit of 5 imports per minute per user. Returns a 404
     * if the importer is not registered or has no data available.
     *
     * @since 1.0.0
     *
     * @param WP_REST_Request $request The request object.
     *
     * @return WP_REST_Response|WP_Error
     */
    public function execute_import( WP_REST_Request $request ) {
        $rate_error = $this->check_rate_limit( 'import', 5, 60 );
        if ( is_wp_error( $rate_error ) ) {
            return $rate_error;
        }

        $source   = $request->get_param( 'source' );
        $importer = ImporterRegistry::init()->get_importer( $source );

        if ( null === $importer || ! $importer->is_available() ) {
            return new WP_Error(
                'importer_not_found',
                __( 'The requested importer is not available.', 'nimblymail-smtp' ),
                array( 'status' => 404 )
            );
        }

        $result = $importer->execute_import();

        return new WP_REST_Response( $result );
    }
}
