<?php

declare(strict_types=1);

namespace BadamSoft\WooProductExporter\Settings;

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

use BadamSoft\WooProductExporter\Access\AccessManager;
use BadamSoft\WooProductExporter\Core\Plugin;
use WP_REST_Request;
use WP_REST_Response;
use WP_REST_Server;

use function __;
use function current_user_can;
use function is_array;
use function rest_ensure_response;
use function sanitize_text_field;
use function wp_unslash;
use function wp_get_current_user;

class SettingsRestController {
    private SettingsRepository $repository;
    private AccessManager $access_manager;
    private Plugin $plugin;

    public function __construct( SettingsRepository $repository, AccessManager $access_manager, Plugin $plugin ) {
        $this->repository      = $repository;
        $this->access_manager  = $access_manager;
        $this->plugin          = $plugin;

        add_action( 'rest_api_init', [ $this, 'register_routes' ] );
    }

    public function register_routes(): void {
        register_rest_route(
            'wc-pce/v1',
            '/settings',
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [ $this, 'get_settings' ],
                'permission_callback' => [ $this, 'can_manage_settings' ],
            ]
        );

        register_rest_route(
            'wc-pce/v1',
            '/settings',
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [ $this, 'save_settings' ],
                'permission_callback' => [ $this, 'can_manage_settings' ],
                'args'                => [
                    'settings' => [
                        'required' => true,
                        'type'     => 'object',
                    ],
                ],
            ]
        );

        register_rest_route(
            'wc-pce/v1',
            '/settings/cleanup',
            [
                'methods'             => WP_REST_Server::CREATABLE,
                'callback'            => [ $this, 'cleanup_now' ],
                'permission_callback' => [ $this, 'can_manage_settings' ],
            ]
        );

        if ( $this->has_license_support() ) {
            register_rest_route(
                'wc-pce/v1',
                '/license/status',
                [
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_license_status' ],
                    'permission_callback' => [ $this, 'can_manage_settings' ],
                ]
            );

            register_rest_route(
                'wc-pce/v1',
                '/license/activate',
                [
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'activate_license' ],
                    'permission_callback' => [ $this, 'can_manage_settings' ],
                    'args'                => [
                        'license' => [
                            'type'     => 'string',
                            'required' => true,
                        ],
                    ],
                ]
            );

            register_rest_route(
                'wc-pce/v1',
                '/license/deactivate',
                [
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'deactivate_license' ],
                    'permission_callback' => [ $this, 'can_manage_settings' ],
                ]
            );
        }
    }

    private function has_license_support(): bool {
        $license_manager_class = '\\BadamSoft\\WooProductExporter\\Licensing\\LicenseManager';
        $license_service_class = '\\BadamSoft\\WooProductExporter\\Licensing\\LicenseService';

        return class_exists( $license_manager_class ) && class_exists( $license_service_class );
    }

    public function can_manage_settings(): bool {
        // Restrict settings management to administrators.
        return current_user_can( 'manage_options' );
    }

    public function get_settings( WP_REST_Request $request ): WP_REST_Response {
        $state = $this->repository->get_state();

        return rest_ensure_response( [ 'settings' => $state ] );
    }

    public function save_settings( WP_REST_Request $request ): WP_REST_Response {
        $raw = $request->get_param( 'settings' );
        $settings = is_array( $raw ) ? wp_unslash( $raw ) : [];

        $saved = $this->repository->save_state( $settings );

        return rest_ensure_response( [ 'settings' => $saved ] );
    }

    public function cleanup_now(): WP_REST_Response {
        $this->plugin->maybe_cleanup_exports();

        return rest_ensure_response(
            [
                'status'  => 'ok',
                'message' => __( 'Cleanup triggered.', 'badamsoft-product-exporter-for-woocommerce' ),
            ]
        );
    }

    public function get_license_status( WP_REST_Request $request ): WP_REST_Response {
        $refresh = (string) $request->get_param( 'refresh' );
        $refresh = in_array( $refresh, [ '1', 'true', 'yes' ], true );

        $service = $this->plugin->get_license_service();

        if ( $refresh && is_object( $service ) && method_exists( $service, 'get_license_status' ) ) {
            try {
                $service->get_license_status( true );
                $this->sync_access_permissions();
            } catch ( \Throwable $exception ) {
                return rest_ensure_response(
                    new \WP_Error( 'license_refresh_failed', $exception->getMessage(), [ 'status' => 400 ] )
                );
            }
        }

        return rest_ensure_response( $this->build_license_payload() );
    }

    public function activate_license( WP_REST_Request $request ) {
        $license = sanitize_text_field( wp_unslash( (string) $request->get_param( 'license' ) ) );
        $service = $this->plugin->get_license_service();

        if ( ! is_object( $service ) || ! method_exists( $service, 'activate' ) ) {
            return rest_ensure_response(
                new \WP_Error( 'license_service_unavailable', __( 'License service is not available.', 'badamsoft-product-exporter-for-woocommerce' ), [ 'status' => 400 ] )
            );
        }

        try {
            $service->activate( $license );
            $this->sync_access_permissions();
        } catch ( \Throwable $exception ) {
            return rest_ensure_response(
                new \WP_Error( 'license_activation_failed', $exception->getMessage(), [ 'status' => 400 ] )
            );
        }

        return rest_ensure_response( $this->build_license_payload() );
    }

    public function deactivate_license() {
        $service = $this->plugin->get_license_service();

        if ( ! is_object( $service ) || ! method_exists( $service, 'deactivate' ) ) {
            return rest_ensure_response(
                new \WP_Error( 'license_service_unavailable', __( 'License service is not available.', 'badamsoft-product-exporter-for-woocommerce' ), [ 'status' => 400 ] )
            );
        }

        try {
            $service->deactivate();
            $this->sync_access_permissions();
        } catch ( \Throwable $exception ) {
            return rest_ensure_response(
                new \WP_Error( 'license_deactivation_failed', $exception->getMessage(), [ 'status' => 400 ] )
            );
        }

        return rest_ensure_response( $this->build_license_payload() );
    }

    /**
     * @return array<string, mixed>
     */
    private function build_license_payload(): array {
        $capabilities = $this->access_manager->get_capability_flags_for_user();
        return [
            'license'      => $this->plugin->get_license_strings(),
            'capabilities' => $capabilities,
        ];
    }

    private function sync_access_permissions(): void {
        $user = wp_get_current_user();
        if ( $user && method_exists( $user, 'get_role_caps' ) ) {
            $user->get_role_caps();
        }
    }
}
