<?php

namespace Booktics\Extensions\Controllers;

use Booktics\Abstracts\Base_Rest_Controller;
use Arraytics\ToolsSdk\Extension as ExtensionManager;
use Arraytics\ToolsSdk\PluginManager;
use WP_HTTP_Response;
use WP_REST_Request;

/**
 * Module Controller
 *
 * @package Booktics/Module
 */
class Module_Controller extends Base_Rest_Controller {
    /**
     * The namespace of this controller's route.
     *
     * @since 1.0.0
     * @var string
     */
    protected $namespace = 'booktics/v1';

    /**
     * The base of this controller's route.
     *
     * @since 1.0.0
     * @var string
     */
    protected $rest_base = 'module';

    /**
     * Extension manager instance
     *
     * @var ExtensionManager
     */
    protected $extensions;

    /**
     * Initialize the class and set its properties.
     */
    public function __construct() {
        $this->extensions        = new ExtensionManager('booktics_available_modules', booktics_modules_list());
        $this->plugin_manager    = new PluginManager();
    }

    /**
     * Register the routes for the objects of the controller.
     *
     * @since 1.0.0
     *
     * @return void
     */
    public function register_routes(): void {
        register_rest_route($this->namespace, '/' . $this->rest_base, [
            [
                'methods'             => \WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_items'],
                'permission_callback' => [$this, 'get_items_permissions_check'],
                'args'                => [
                    'type' => [
                        'description' => __('Type of extensions to retrieve (module, addon, plugin, all).', 'booktics'),
                        'type'        => 'string',
                        'enum'        => ['module', 'addon', 'plugin', 'all'],
                        'default'     => 'all',
                    ],
                ],
            ],
            [
                'methods'             => \WP_REST_Server::EDITABLE,
                'callback'            => [$this, 'update_item'],
                'permission_callback' => [$this, 'update_item_permissions_check'],
            ],
        ]);
    }

    /**
     * Check if a given request has permission to get items.
     *
     * @since 1.0.0
     *
     * @param WP_REST_Request $request Full data about the request.
     * @return bool True if the request has read access, false otherwise.
     */
    public function get_items_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Check if a given request has permission to update items.
     *
     * @since 1.0.0
     *
     * @param WP_REST_Request $request Full data about the request.
     * @return bool True if the request has update access, false otherwise.
     */
    public function update_item_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Get all extensions
     *
     * @since 1.0.0
     *
     * @param WP_REST_Request $request Full data about the request.
     * @return WP_HTTP_Response Response object on success, or WP_Error object on failure.
     */
    public function get_items($request) {
        $type = ! empty( $request['type'] ) ? sanitize_key( $request['type'] ) : 'all';

        $types = [
            'module' => $this->extensions->get_modules(),
            'addon'  => $this->extensions->get_addons(),
            'plugin' => $this->extensions->get_plugins(),
            'all'    => $this->extensions->get()
        ];

        if (!isset($types[$type])) {
            return $this->error(
                __('Invalid extension type', 'booktics'),
                400,
                'invalid_extension_type'
            );
        }

        foreach ($types[$type] as $data) {
            $modules_list[] = $data;
        }

        return $this->response($modules_list);
    }

    /**
     * Update extension status
     *
     * @since 1.0.0
     *
     * @param WP_REST_Request $request Full data about the request.
     * @return WP_HTTP_Response Response object on success, or WP_Error object on failure.
     */
    public function update_item($request) {
        $params = json_decode( $request->get_body(), true);

        $name   = isset($params['name']) ? sanitize_text_field($params['name']) : '';
        $status = isset($params['status']) ? sanitize_text_field($params['status']) : '';

        $valid_statuses = ['off', 'on', 'install', 'activate', 'deactivate', 'upgrade'];

        if (empty($name)) {
            return $this->error(
                __('Please enter extension name', 'booktics'),
                422,
                'extension_name_error'
            );
        }

        if (empty($status)) {
            return $this->error(
                /* translators: %s: extension name */
                sprintf(__('Please provide status for extension %s', 'booktics'), $name),
                422,
                'extension_status_error'
            );
        }

        if (!in_array($status, $valid_statuses, true)) {
            return $this->error(
                /* translators: %s: extension status */
                sprintf(__('Invalid status %s provided', 'booktics'), $status),
                422,
                'invalid_status'
            );
        }

        $extension = $this->extensions->find($name);

        if (!$extension) {
            return $this->error(
                /* translators: %s: extension name */
                sprintf(__('Extension %s not found', 'booktics'), $name),
                404,
                'extension_not_found'
            );
        }

        if ( 'module' == $extension['type'] ) {
            $result = $this->extensions->update($name, $status);

            if (false === $result) {
                return $this->error(
                    /* translators: %s: extension name */
                    sprintf(__('Could not turn %s the module', 'booktics'), $status),
                    500,
                    'operation_failed'
                );
            }

            $this->update_relevant_settings($name, $status);

            return $this->response( [ 
                'name'   => $name, 
                'status' => $status 
            ],
            /* translators: %s: extension name */
            sprintf( __('Module turned %s successfully', 'booktics'), $status) );
        }

        // When updating plugin status using tools-sdk change actual plugin status
        if ( 'plugin' === $extension['type'] ) {
            switch ( $status ) {
                case 'install':
                    $result = $this->plugin_manager->install_plugin($name);
                    break;
                case 'activate':
                    $result = $this->plugin_manager->activate_plugin($name);
                    break;
                case 'deactivate':
                    $result = $this->plugin_manager->deactivate_plugin($name);
                    break;
                case 'upgrade':
                    return $this->response( [ 'redirect_url' => $extension['upgrade_link'] ] );
                    break;
            }

            if ( false === $result ) {
                return $this->error(
                    /* translators: %s: extension name */
                    sprintf(__('Could not %s the extension', 'booktics'), $status),
                    500,
                    'operation_failed'
                );
            }
        }

        return $this->response([
            'name'   => $name,
            'status' => $status,
        ],
        /* translators: %s: extension name */
        sprintf(__('Extension %s successfully', 'booktics'), $status)
        );
    }

    /**
     * Update relevant settings based on extension status
     *
     * @since 1.0.0
     *
     * @param string $extension_name   Extension name.
     * @param string $extension_status Extension status.
     * @return void
     */
    public function update_relevant_settings($extension_name, $extension_status) {
        $is_enabled = $extension_status === 'on';

        switch ($extension_name) {
            case 'stripe':
                booktics_update_option('stripe_addon_install_status', $is_enabled ? 1 : 0);
                booktics_update_option('enable_stripe', $is_enabled);
                break;

            case 'paypal':
                booktics_update_option('paypal_connected', $is_enabled);
                booktics_update_option('enable_paypal', $is_enabled);
                break;

            case 'google-calendar':
                booktics_update_option('google_redirect_url', booktics_get_auth_redirect_uri('google-auth'));
                booktics_update_option('google_calendar_connected', false);
                booktics_update_option('enable_google_calendar', $is_enabled);
                break;

            case 'outlook-calendar':
                booktics_update_option('microsoft_redirect_url', booktics_get_auth_redirect_uri('microsoft-auth'));
                booktics_update_option('enable_outlook_calendar', $is_enabled);
                break;

            case 'fluentcrm':
                booktics_update_option('enable_fluentcrm', $is_enabled);
                break;
        }
    }
}


