<?php

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

require_once(CHURNSOLUTION_DIR . "/classes/class-churnsolution-stripe-gateway.php");
require_once(CHURNSOLUTION_DIR . "/util/class-currency-utils.php");


class Churnsolution_Subscription_Controller
{

    // Here initialize our namespace and resource name.
    /**
     * @var string
     */
    private $namespace;

    /**
     * @var string
     */
    private $resource_name;

    public function __construct()
    {
        $this->namespace = '/churnsolution/v1';
        $this->resource_name = 'subscription';
    }

    // Register our routes.
    public function register_routes()
    {
        register_rest_route($this->namespace, '/' . $this->resource_name, array(
            array(
                'methods' => 'GET',
                'callback' => array($this, 'get_subscription'),
            )
        ));

        register_rest_route($this->namespace, '/' . $this->resource_name . '/apply-coupon', array(
            array(
                'methods' => 'POST',
                'callback' => array($this, 'apply_coupon'),
            )
        ));

        register_rest_route($this->namespace, '/' . $this->resource_name . '/extend-free-trial', array(
            array(
                'methods' => 'POST',
                'callback' => array($this, 'extend_free_trial'),
            )
        ));

        register_rest_route($this->namespace, '/' . $this->resource_name . '/pause', array(
            array(
                'methods' => 'POST',
                'callback' => array($this, 'pause_subscription'),
            )
        ));

        register_rest_route($this->namespace, '/' . $this->resource_name . '/sync-subscription', array(
            array(
                'methods' => 'POST',
                'callback' => array($this, 'sync_subscription'),
            )
        ));

        register_rest_route($this->namespace, '/' . $this->resource_name . '/cancel', array(
            array(
                'methods' => 'POST',
                'callback' => array($this, 'cancel'),
            )
        ));

    }

    function get_subscription(WP_REST_Request $args)
    {

        if (class_exists('PMPro_Subscription')) {
            $current_user = wp_get_current_user();
            $level_id = $args->get_param('level_id');
            return $this->get_pmpro_subscription_details($current_user->ID, $level_id);
        }

        if (class_exists('WC_Subscription')) {
            $subscription_id = (int) $args->get_param('subscription_id');
            $subscription = wcs_get_subscription($subscription_id);
            return [
                'external_id' => (string) $subscription->get_id(),
                'status' => $subscription->get_status(),
                'start_date' => $subscription->get_date('start'),
                'end_date' => $subscription->get_date('end'),
                'next_payment_date' => $subscription->get_date('next_payment'),
                'billing_interval' => $subscription->get_billing_interval(),
                'billing_period' => $subscription->get_billing_period(),
                'customer_id' => $subscription->get_customer_id(),
                'total' => $subscription->get_total(),
                'items' => array_map(function ($item) {
                    return [
                        'name' => $item->get_name(),
                        'product_id' => $item->get_product_id(),
                        'quantity' => $item->get_quantity(),
                        'total' => $item->get_total(),
                    ];
                }, $subscription->get_items()),
            ];
        }

        return new stdClass;
    }

    function sync_subscription(WP_REST_Request $args)
    {
        $current_user = wp_get_current_user();
        $user_id = $current_user->ID;

        Churnsolution_Stripe_Gateway::sync_pmpro_subscription($user_id);

        return new stdClass;

    }

    function cancel(WP_REST_Request $args)
    {
        if (class_exists('PMPro_Subscription')) {
            $current_user = wp_get_current_user();

            $user_id = $current_user->ID;
            $level_id = $args->get_param('level_id');

            Churnsolution_Stripe_Gateway::cancel_subscription_via_pmpro($current_user, $level_id);

        }

        if (class_exists('WC_Subscription')) {
            $current_user = wp_get_current_user();
            $subscription_id = (int) $args->get_param('subscription_id');
            $subscription = wcs_get_subscription($subscription_id);
            
            if ($subscription->get_user_id() !== $current_user->ID) {
                return new WP_REST_Response(['error' => 'Unauthorized'], 403);
            }
            if ($subscription->get_status() !== 'cancelled') {
                $subscription->update_status('cancelled');
                return new WP_REST_Response(['message' => 'Subscription cancelled.']);
            } else {
                return new WP_REST_Response(['message' => 'Subscription already cancelled.'], 400);
            }
        }
    }

    function pause_subscription(WP_REST_Request $args)
    {

        if (class_exists('PMPro_Subscription')) {
            $current_user = wp_get_current_user();
            $level_id = $args->get_param('level_id');

            $subscription = $this->get_pmpro_subscription_details($current_user->ID, $level_id);

            $subscription_external_id = $subscription['external_id'];

            $number_of_months = $args['number_of_months'];

            Churnsolution_Stripe_Gateway::pause($subscription_external_id, $number_of_months);

        }

        return new stdClass;
    }

    function apply_coupon(WP_REST_Request $args)
    {

        if (class_exists('PMPro_Subscription')) {
            $current_user = wp_get_current_user();
            $level_id = $args->get_param('level_id');

            $subscription = $this->get_pmpro_subscription_details($current_user->ID, $level_id);

            $subscription_external_id = $subscription['external_id'];

            $coupon_code = $args['coupon_code'];

            Churnsolution_Stripe_Gateway::apply_coupon($subscription_external_id, $coupon_code);
        }

    }

    function extend_free_trial(WP_REST_Request $args)
    {

        if (class_exists('PMPro_Subscription')) {
            $current_user = wp_get_current_user();
            $level_id = $args->get_param('level_id');

            $subscription = $this->get_pmpro_subscription_details($current_user->ID, $level_id);

            $subscription_external_id = $subscription['external_id'];

            $number_of_days = $args['number_of_days'];

            Churnsolution_Stripe_Gateway::extend_free_trial($subscription_external_id, $number_of_days);
        }

    }

    private function get_pmpro_subscription_details($user_id, $level_id)
    {

        $subscription = PMPro_Subscription::get_subscription(array("user_id" => $user_id, "level_id" => (int)$level_id));

        $subscription_data = array(
            "external_id" => null
        );

        if (!empty($subscription)) {
            $external_id = $subscription->get_subscription_transaction_id();
            $external_subscription = Churnsolution_Stripe_Gateway::get_external_subscription($external_id);

            if (!empty($external_subscription)) {

                if ($external_subscription->status != 'canceled') {
                    $upcoming_invoice = Churnsolution_Stripe_Gateway::get_external_upcoming_invoice($external_id);

                    if (!empty($upcoming_invoice)) {
                        $mapped_upcoming_invoice = array(
                            "amount_due" => Currency_Utils::getShortestFormFromLong($upcoming_invoice->amount_due, $upcoming_invoice->currency),
                            "currency" => $upcoming_invoice->currency,
                            "currency_symbol" => Currency_Utils::getSymbol($upcoming_invoice->currency),
                            "created" => $upcoming_invoice->created,
                            "total_excluding_tax" => Currency_Utils::getShortestFormFromLong($upcoming_invoice->total_excluding_tax, $upcoming_invoice->currency),
                            "applied_balance" => Currency_Utils::getShortestFormFromLong($upcoming_invoice->applied_balance, $upcoming_invoice->currency),
                            "tax" => $upcoming_invoice->tax == null ? null :
                                Currency_Utils::getShortestFormFromLong($upcoming_invoice->tax, $upcoming_invoice->currency),
                        );
                    }

                    if(!empty($upcoming_invoice->total_discount_amounts)){
                        $total_discounts = 0;

                        foreach ($upcoming_invoice->total_discount_amounts as $discount){
                            $total_discounts += $discount->amount;
                        }

                        $mapped_upcoming_invoice['total_discounts'] = $total_discounts;
                    }

                }


                $subscription_data['status'] = $subscription->get_status();
                $subscription_data['external_id'] = $external_id;
                $subscription_data['upcoming_invoice'] = $mapped_upcoming_invoice;
                $subscription_data['pause_collection'] = $external_subscription->pause_collection;
            }
        }

        return $subscription_data;
    }

}

// Function to register our new routes from the controller.
function churnsolution_register_subscription_routes()
{
    $controller = new Churnsolution_Subscription_Controller();
    $controller->register_routes();
}

add_action('rest_api_init', 'churnsolution_register_subscription_routes');
