<?php

namespace Dolphy\Plugin\WooCommerce\Gateways;

use Dolphy\Plugin\Exceptions\Exception;
use Dolphy\Plugin\Helpers\Crypto;
use Dolphy\Plugin\Helpers\WooCommerce;
use Dolphy\Plugin\Option\Payment\Flutterwave as FlutterwaveOption;
use Exception as GlobalException;
use WC_Payment_Gateway;

if (WooCommerce::isPaymentGatewayActive() && WooCommerce::isFlutterwaveEnabled()) {

  class Flutterwave extends WC_Payment_Gateway {

    function __construct() {
      $this->id = 'flutterwave';
      $this->icon = DOLPHY_ASSETS.'/images/flutterwave-small.png';
      $this->has_fields = true; // in case you need a custom credit card form
      $this->method_title = 'Flutterwave';
      $this->method_description = 'One platform that lets you sell wherever your customers are - online, in‑person, anywhere in the world, and everywhere in‑between.';

      // gateways can support subscriptions, refunds, saved payment methods,
      // but in this tutorial we begin with simple payments
      $this->supports = array(
        'products'
      );

      // Method with all the options fields
      $this->init_form_fields();

      // Load the settings.
      $this->init_settings();

      $flutterwave = FlutterwaveOption::instance();

      $this->title = $this->get_option('title');
      if (empty($this->title)) {
        $this->title = $flutterwave->title;
      }

      $this->description = $this->get_option('description');
      if (empty($this->description)) {
        $this->description = $flutterwave->description;
      }

      $this->enabled = $this->get_option('enabled');

      // This action hook saves the settings
      add_action("woocommerce_update_options_payment_gateways_{$this->id}", array($this, 'process_admin_options'));

      // We need custom JavaScript to obtain a token
      add_action('wp_enqueue_scripts', array($this, 'payment_scripts'));

      // You can also register a webhook here
      // add_action('woocommerce_api_Dolphy-pay-flutterwave', array($this, 'pay_with_flutterwave'));
      add_action('woocommerce_api_Dolphy-verify-flutterwave', array($this, 'webhook'));
    }

    public function init_form_fields() {
      $flutterwave = FlutterwaveOption::instance();

      $this->form_fields = array(
        'enabled' => array(
          'title'       => 'Enable/Disable',
          'label'       => 'Enable Flutterwave Gateway',
          'type'        => 'checkbox',
          'description' => '',
          'default'     => 'no'
        ),

        'title' => array(
          'title'       => 'Title',
          'type'        => 'text',
          'description' => 'This controls the title which the user sees during checkout.',
          'default'     => $flutterwave->title,
        ),

        'description' => array(
          'title'       => 'Description',
          'type'        => 'textarea',
          'description' => 'This controls the description which the user sees during checkout.',
          'default'     => $flutterwave->description,
        ),

      );
    }

    public function payment_fields() {
      echo wpautop(wp_kses_post($this->description));
    }

    public function payment_scripts() {
      if (!is_cart() && !is_checkout()) return;

      wp_enqueue_script('flutterwave', 'https://api.ravepay.co/flwv3-pug/getpaidx/api/flwpbf-inline.js', array(), true);
    }

    public function validate_fields() {
      //
    }

    public function process_payment($orderId) {
      $flutterwave = FlutterwaveOption::instance();

      try {
        if (!($order = wc_get_order($orderId))) {
          throw new Exception('Unable to retrieve order!');
        }

        $user = $order->get_user();
        $amount = $order->get_total();
        // $returnUrl = $this->get_return_url($order);

        $returnUrl = site_url("/wc-api/Dolphy-verify-flutterwave/?order_id={$orderId}");

        if ($phone = get_user_meta($user->ID, 'user_phone', true)) {
          $data['customer_phone'] = $phone;
        }

        $info = parse_url(site_url());
        $refDetails = array($info['host'], $order->get_id(), time());
        $reference = hash('sha1', implode('|||', $refDetails));

        $data['PBFPubKey'] = $flutterwave->publicKey;
        $data['customer_email'] = $user->user_email;
        $data['amount'] = $amount;
        $data['currency'] = 'NGN';
        $data['txref'] = $reference;
        $data['redirect_url'] = $returnUrl;
        $data['meta'][] = array(
          'metaname' => 'orderId',
          'metavalue' => $order->get_id()
        );

        $param = json_encode($data);

        return array(
          'result' => 'success',
          'redirect' => "javascript:CYB.Flutterwave.pay({$param});"
        );
      } catch (GlobalException $e) {
        wc_add_notice($e->getMessage(), 'error');
      }
    }

    public function webhook() {
      global $woocommerce;

      $flutterwave = FlutterwaveOption::instance();

      try {
        if (!array_key_exists('reference', $_GET)) {
          throw new Exception('Transaction Reference not found!');
        }

        $reference = sanitize_key($_GET['reference']);

        $body['SECKEY'] = $flutterwave->secretKey;
        $body['txref'] = $reference;

        $url = 'https://api.ravepay.co/flwv3-pug/getpaidx/api/v2/verify';

        $args['body'] = json_encode($body);
        $args['headers']['Content-Type'] = 'application/json';

        $resp = wp_remote_post($url, $args);

        if (is_wp_error($resp)) {
          throw new Exception($resp->get_error_message());
        }

        $info = wp_remote_retrieve_body($resp);
        $info = json_decode($info);

        if ($info->status !== 'success') {
          throw new Exception($info->message);
        }

        $data = $info->data;
        $orderId = NULL;

        foreach ($data->meta as $meta) {
          if ($meta->metaname !== 'orderId') continue;
          $orderId = $meta->metavalue; break;
        }

        if (is_null($orderId)) {
          throw new Exception('Order ID not found!');
        }

        if (!($order = wc_get_order($orderId))) {
          throw new Exception('Order does not exist!');
        }

        $returnUrl = $this->get_return_url($order);
        $orderStatus = $order->get_status();

        if ($orderStatus === 'completed') {
          throw new Exception('This order has already been completed!');
        }

        if ($orderStatus !== 'pending') {
          throw new Exception('This order is currently not pending!');
        }

        if ($data->status != 'successful') {
          $order->update_status('failed', 'You payment failed with status: '.$data->vbvmessage);
          wp_redirect($returnUrl);
        }

        if ($data->amount < $order->get_total()) {
          throw new Exception('Amount paid is lower than order amount!');
        }

        $order->payment_complete();
        $order->reduce_order_stock();

        $order->add_order_note('Your payment has been received. We will get back to you shortly. Thank you!', true);

        // Empty cart
        $woocommerce->cart->empty_cart();

        wp_redirect($returnUrl);

      } catch (GlobalException $e) {
        wp_die($e->getMessage(), 401);
      }
    }

  }

}
