<?php
defined( 'ABSPATH' ) || exit;

/**
 * REST API for the Class-Based Styling System — reusable, site-wide CSS
 * classes. Mirrors the route/permission patterns already used in Jalpi_API.
 */
class Jalpi_Classes_API {

    private static $instance = null;
    const NAMESPACE = 'jalpi-page-builder/v1';

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

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

    public function register_routes() {
        register_rest_route( self::NAMESPACE, '/classes', [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_classes' ],
                'permission_callback' => [ $this, 'edit_permission' ],
                'args'                => [
                    'search'   => [ 'required' => false, 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field' ],
                    'favorite' => [ 'required' => false, 'type' => 'boolean' ],
                ],
            ],
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [ $this, 'create_class' ],
                'permission_callback' => [ $this, 'edit_permission' ],
                'args'                => [
                    'name' => [ 'required' => true, 'type' => 'string' ],
                ],
            ],
        ] );

        register_rest_route( self::NAMESPACE, '/classes/reorder', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'reorder_classes' ],
            'permission_callback' => [ $this, 'edit_permission' ],
            'args'                => [
                'keys' => [ 'required' => true, 'type' => 'array' ],
            ],
        ] );

        register_rest_route( self::NAMESPACE, '/classes/export', [
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => [ $this, 'export_classes' ],
            'permission_callback' => [ $this, 'edit_permission' ],
        ] );

        register_rest_route( self::NAMESPACE, '/classes/import', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'import_classes' ],
            'permission_callback' => [ $this, 'edit_permission' ],
            'args'                => [
                'classes'           => [ 'required' => true, 'type' => 'array' ],
                'conflict_strategy' => [ 'required' => false, 'type' => 'string', 'default' => 'skip' ],
            ],
        ] );

        register_rest_route( self::NAMESPACE, '/classes/(?P<key>[a-z0-9_]+)', [
            [
                'methods'             => 'PATCH',
                'callback'            => [ $this, 'update_class' ],
                'permission_callback' => [ $this, 'edit_permission' ],
            ],
            [
                'methods'             => WP_REST_Server::DELETABLE,
                'callback'            => [ $this, 'delete_class' ],
                'permission_callback' => [ $this, 'edit_permission' ],
            ],
        ] );

        register_rest_route( self::NAMESPACE, '/classes/(?P<key>[a-z0-9_]+)/duplicate', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'duplicate_class' ],
            'permission_callback' => [ $this, 'edit_permission' ],
        ] );

        register_rest_route( self::NAMESPACE, '/classes/(?P<key>[a-z0-9_]+)/favorite', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [ $this, 'toggle_favorite' ],
            'permission_callback' => [ $this, 'edit_permission' ],
        ] );

        register_rest_route( self::NAMESPACE, '/classes/(?P<key>[a-z0-9_]+)/usage', [
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => [ $this, 'get_usage' ],
            'permission_callback' => [ $this, 'edit_permission' ],
        ] );
    }

    /**
     * Classes are a shared, site-wide resource (not scoped to one post), so
     * this simply requires the general edit_posts capability — the same
     * baseline Jalpi_API::edit_permission() falls back to when no post_id is present.
     */
    public function edit_permission(): bool {
        return is_user_logged_in() && current_user_can( 'edit_posts' );
    }

    // -------------------------------------------------------------------------
    // Route callbacks
    // -------------------------------------------------------------------------

    public function get_classes( WP_REST_Request $request ): WP_REST_Response {
        $manager = Jalpi_Class_Manager::instance();
        $classes = $manager->get_all();

        $search = strtolower( (string) $request->get_param( 'search' ) );
        if ( '' !== $search ) {
            $classes = array_values( array_filter( $classes, function ( $c ) use ( $search ) {
                return false !== strpos( strtolower( $c['name'] ), $search );
            } ) );
        }

        if ( null !== $request->get_param( 'favorite' ) && rest_sanitize_boolean( $request->get_param( 'favorite' ) ) ) {
            $classes = array_values( array_filter( $classes, static fn( $c ) => $c['favorite'] ) );
        }

        return rest_ensure_response( $classes );
    }

    public function create_class( WP_REST_Request $request ) {
        $data      = Jalpi_Sanitizer::sanitize_class_definition( (array) $request->get_json_params() );
        $name      = $data['name'] ?: sanitize_text_field( (string) $request->get_param( 'name' ) );
        $created   = Jalpi_Class_Manager::instance()->create( $name, $data );

        if ( ! $created ) {
            return new WP_Error( 'create_failed', __( 'Could not create class.', 'jalpi-page-builder' ), [ 'status' => 500 ] );
        }
        return rest_ensure_response( $created );
    }

    public function update_class( WP_REST_Request $request ) {
        $key  = sanitize_key( $request->get_param( 'key' ) );
        $data = Jalpi_Sanitizer::sanitize_class_definition( (array) $request->get_json_params() );

        $updated = Jalpi_Class_Manager::instance()->update( $key, $data );
        if ( ! $updated ) {
            return new WP_Error( 'not_found', __( 'Class not found.', 'jalpi-page-builder' ), [ 'status' => 404 ] );
        }
        return rest_ensure_response( $updated );
    }

    public function delete_class( WP_REST_Request $request ) {
        $key     = sanitize_key( $request->get_param( 'key' ) );
        $deleted = Jalpi_Class_Manager::instance()->delete( $key );
        return rest_ensure_response( [ 'deleted' => $deleted ] );
    }

    public function duplicate_class( WP_REST_Request $request ) {
        $key       = sanitize_key( $request->get_param( 'key' ) );
        $duplicate = Jalpi_Class_Manager::instance()->duplicate( $key );
        if ( ! $duplicate ) {
            return new WP_Error( 'not_found', __( 'Class not found.', 'jalpi-page-builder' ), [ 'status' => 404 ] );
        }
        return rest_ensure_response( $duplicate );
    }

    public function toggle_favorite( WP_REST_Request $request ) {
        $key     = sanitize_key( $request->get_param( 'key' ) );
        $updated = Jalpi_Class_Manager::instance()->toggle_favorite( $key );
        if ( ! $updated ) {
            return new WP_Error( 'not_found', __( 'Class not found.', 'jalpi-page-builder' ), [ 'status' => 404 ] );
        }
        return rest_ensure_response( $updated );
    }

    public function get_usage( WP_REST_Request $request ): WP_REST_Response {
        $key = sanitize_key( $request->get_param( 'key' ) );
        return rest_ensure_response( [ 'count' => Jalpi_Class_Manager::instance()->global_usage_count( $key ) ] );
    }

    public function reorder_classes( WP_REST_Request $request ): WP_REST_Response {
        $keys = (array) $request->get_param( 'keys' );
        Jalpi_Class_Manager::instance()->reorder( $keys );
        return rest_ensure_response( [ 'success' => true ] );
    }

    public function export_classes(): WP_REST_Response {
        return rest_ensure_response( [
            'version' => JALPI_VERSION,
            'classes' => Jalpi_Class_Manager::instance()->export_all(),
        ] );
    }

    public function import_classes( WP_REST_Request $request ): WP_REST_Response {
        $classes  = (array) $request->get_param( 'classes' );
        $strategy = sanitize_key( (string) $request->get_param( 'conflict_strategy' ) ) ?: 'skip';
        $result   = Jalpi_Class_Manager::instance()->import( $classes, $strategy );
        return rest_ensure_response( $result );
    }
}
