<?php
// phpcs:ignoreFile WordPress.Security.NonceVerification.Recommended
// phpcs:ignoreFile WordPress.Security.ValidatedSanitizedInput.InputNotValidated
// phpcs:ignoreFile WordPress.Security.ValidatedSanitizedInput.MissingUnslash
// phpcs:ignoreFile WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

class SLN_Payment_Stripe
{
    protected $plugin;

    public function __construct(SLN_Plugin $plugin)
    {
        $this->plugin = $plugin;
    }

    public static function getWebhookUrl($isPayRemainingAmount = false)
    {
        $url = add_query_arg(['sln_action' => 'stripe_webhook', 'pay_remaining_amount' => $isPayRemainingAmount ? 1 : 0], home_url('/'));
        return apply_filters('sln.payment.stipe.webhookurl', $url);
    }

    public function execute()
    {
        if (!isset($_GET['sln_action']) || $_GET['sln_action'] !== 'stripe_webhook') {
            return;
        }
        $this->initApi();

        $webhook_endpoints = get_option('sln_stripe_webhook_endpoints') ?? array();
        $current_url = SLN_Func::currPageUrl();

        $endpoints = \Stripe\WebhookEndpoint::all();

        $endpoint = false;
        foreach($endpoints as $ep) {
            foreach($webhook_endpoints as $webhook_endpoint) {
                if ($current_url === $webhook_endpoint['url'] && $current_url === $ep->url && $webhook_endpoint['id'] === $ep->id) {
                    $endpoint = $webhook_endpoint;
                }
            }
        }

        if ( ! $endpoint ) {
            return;
        }

        $endpoint_secret = $endpoint['secret'];

        $payload = @file_get_contents('php://input');
        $sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
        $event = null;

        try {
            $event = \Stripe\Webhook::constructEvent(
                $payload, $sig_header, $endpoint_secret
            );
        } catch(\UnexpectedValueException $e) {
            // Invalid payload
            http_response_code(400);
            exit();
        } catch(\Stripe\Exception\SignatureVerificationException $e) {
            // Invalid signature
            http_response_code(400);
            exit();
        }

        // Handle the event
        switch ($event->type) {
            case 'checkout.session.completed':
                $checkoutSession = $event->data->object; // contains a \Stripe\Checkout\Session
                // Then define and call a method to handle the successful payment intent.
                // handlePaymentIntentSucceeded($paymentIntent);
                break;
        }

        $payRemainingAmount = isset($_GET['pay_remaining_amount']) && $_GET['pay_remaining_amount'];

        if ($checkoutSession) {
            $statuses = array(SLN_Enum_BookingStatus::PENDING_PAYMENT, SLN_Enum_BookingStatus::DRAFT);
            if ($payRemainingAmount) {
                $statuses[] = SLN_Enum_BookingStatus::PAID;
            }
            $booking  = $this->plugin->getRepository(SLN_Plugin::POST_TYPE_BOOKING)->getOne(array(
                'post_status' => $statuses,
                '@wp_query'   => array(
                    'meta_query' => array(
                        array(
                            'key'     => '_sln_booking_stripe_session_id',
                            'value'   => $checkoutSession->id,
                            'compare' => '=',
                        )
                    ),
                )
            ));

            $paymentIntent = \Stripe\PaymentIntent::retrieve($checkoutSession->payment_intent);
        }

        if ($booking) {
            try {
                $paymentIntent = \Stripe\PaymentIntent::update($paymentIntent->id, array(
                        'description' => "Booking #" . $booking->getId(),
                ));
                $checkShop = True;
                if(defined('SLNMS_VERSION')){
                    $musltishop = \SalonMultishop\Addon::getInstance()->getCurrentShop()->getId();
                    if($musltishop != $booking->getMeta('shop')){
                        $checkShop = false;
                    }
                }

                if ($paymentIntent->status === 'succeeded' && $checkShop) {
                    $transactionID = $paymentIntent->charges->data[0]->balance_transaction;
                    $booking->markPaid($transactionID, $payRemainingAmount ? $booking->getRemaingAmountAfterPay(false) : 0);
                }

            } catch (Exception $ex) {
                    SLN_Plugin::addLog('stripe error: ' . $ex->getMessage());
            }
        }

        header('HTTP/1.1 200 OK');

        exit();

    }

    protected function initApi() {

        if ( ! class_exists('Stripe\Stripe') ) {
            require_once __DIR__ . '/../PaymentMethod/_stripe/vendor/autoload.php';
        }

        \Stripe\Stripe::setApiKey($this->plugin->getSettings()->get('pay_stripe_apiKey'));
    }

}
