<?php

namespace Booktics\Settings\Controllers;

use Booktics\Abstracts\Base_Rest_Controller;
use Booktics\Services\Schedule_Manager;
use Booktics\Settings\Settings;
use WP_Error;
use WP_HTTP_Response;
use WP_REST_Request;
use WP_REST_Server;

if ( ! function_exists( 'is_plugin_active' ) ) {
    require_once ABSPATH . 'wp-admin/includes/plugin.php';
}

/**
 * Settings controller
 *
 * @package Booktics/Appointment
 */
class Settings_Controller extends Base_Rest_Controller {
    /**
     * Endpoint namespace
     *
     * @var string
     */
    protected $namespace = 'booktics/v1';

    /**
     * Route name
     *
     * @var string
     */
    protected $rest_base = 'settings';

    /**
     * Register routes
     *
     * @return  void
     */
    public function register_routes(): void {
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_item' ),
                    'args'                => array(),
                    'permission_callback' => array( $this, 'get_item_permissions_check' ),
                ),
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'update_item' ),
                    'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
                    'permission_callback' => array(
                        $this,
                        'get_item_permissions_check',
                    ),
                ),
                'schema' => array( $this, 'get_public_item_schema' ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/public',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_public_item' ),
                    'args'                => array(),
                    'permission_callback' => array(
                        $this,
                        'get_public_item_permissions_check',
                    ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/stripe/disconnect',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array(
                        $this,
                        'stripe_disconnect',
                    ),
                    'permission_callback' => array(
                        $this,
                        'stripe_disconnect_permissions_check',
                    ),
                ),
            )
        );
    }

    /**
     * Check if a given request has access to get items.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_Error
     */
    public function get_item_permissions_check( $request ): bool {
        return current_user_can( 'manage_options' );
    }

    /**
     * Format settings for API response.
     *
     * @param array $settings Settings array.
     *
     * @return array
     */
    private function format_settings_for_response( array $settings ): array {
        $settings['reschedule_restriction']      = empty( $settings['reschedule_restriction'] ) ? (object) array() : $settings['reschedule_restriction'];
        $settings['custom_reschedule_status']    = empty( $settings['custom_reschedule_status'] ) ? (object) array() : $settings['custom_reschedule_status'];
        $settings['cancellation_restriction']    = empty( $settings['cancellation_restriction'] ) ? (object) array() : $settings['cancellation_restriction'];
        $settings['stripe_addon_install_status'] = 0;

        $settings = apply_filters( 'booktics_format_setting_response', $settings );

        return $settings;
    }

    /**
     * Get a collection of items.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return WP_HTTP_Response
     */
    public function get_item( $request ) {
        $settings = Settings::get();
        $settings = apply_filters( 'booktics_rest_settings', $settings );
        $settings = $this->format_settings_for_response( $settings );

        return $this->response( $settings, __( 'Settings fetched successfully.', 'booktics' ) );
    }

    /**
     * Update plugin settings.
     *
     * @param WP_Rest_Request $request Request object.
     *
     * @return WP_HTTP_Response
     */
    public function update_item( $request ) {
        $params = $request->get_params();

        if ( isset( $params['schedule'] ) || isset( $params['custom'] ) || isset( $params['holiday'] ) ) {
            $input_data       = json_decode( $request->get_body(), true );
            $schedule_manager = Schedule_Manager::make( $input_data );
            $schedule_manager->save();
            unset( $params['schedule'], $params['custom'], $params['holiday'] );
        }

        Settings::update( $params );

        $settings = Settings::get();
        $settings = apply_filters( 'booktics_rest_settings', $settings );
        $settings = $this->format_settings_for_response( $settings );

        return $this->response( $settings, __( 'Settings updated successfully.', 'booktics' ) );
    }

    /**
     * Get public settings
     */
    public function get_public_item( $request ) {
        $all     = Settings::get();
        $allowed = [
            'primary_color',
            'secondary_color',
            'currency',
            'currency_symbol_position',
            'currency_decimals',
            'currency_price_separator',
            'enable_stripe_payment',
            'enable_paypal_payment',
            'enable_local_payment',
            'stripe_publishable_key',
            'show_end_time',
            'calendar_locale',
            'allow_customer_rescheduling',
            'allow_customer_cancellation',
            'reschedule_restriction',
            'cancellation_restriction',
        ];

        $public = array_intersect_key( $all, array_flip( $allowed ) );
        $public = apply_filters( 'booktics_rest_public_settings', $public );

        return $this->response( $public, __( 'Public settings fetched successfully.', 'booktics' ) );
    }

    /**
     * Check if a given request has access to get items.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return bool
     */
    public function get_public_item_permissions_check( $request ): bool {
        return true;
    }

    /**
     * Check if a given request has access to get items.
     *
     * @param WP_REST_Request $request Full data about the request.
     *
     * @return bool
     */
    public function stripe_disconnect_permissions_check( $request ): bool {
        return current_user_can( 'manage_options' );
    }

    /**
     * Disconnect Stripe account by clearing account ID
     *
     * @param $request
     *
     * @return WP_HTTP_Response
     */
    public function stripe_disconnect( $request ) {
        Settings::update( 'stripe_account_id', '' );
        Settings::update( 'stripe_account_type', '' );

        return $this->response( array(), __( 'Successfully disconnected Stripe account.', 'booktics' ) );
    }
}
