<?php

  class pm_opennode {
    public $id = __CLASS__;
    public $name = 'Opennode';
    public $description = '';
    public $author = 'Manicato LLC';
    public $version = '1.0';
    public $website = 'https://syscoop.co/';
    public $priority = 1;

    public function options($items, $subtotal, $tax, $currency_code, $customer) {

      if (empty($this->settings['status'])) return;

      return array(
        'title' => 'Opennode',
        'options' => array(
          array(
            'id' => 'opennode',
            'icon' => $this->settings['icon'],
            'name' => 'Bitcoin, for everyday!',
            'description' => language::translate(__CLASS__.':description', 'Secure payments via Opennode: Bitcoin, for everyday!'),
            'fields' => '',
            'cost' => 0,
            'tax_class_id' => 0,
            'confirm' => language::translate('title_pay_with_opennode', 'Pay With Opennode: Bitcoin, for everyday!'),
          ),
        ),
      );
    }

    public function transfer($order) {

      try {

        $order->save();

        $description = '';
        foreach ($order->data['items'] as $item) {
          $description .= (string)(float)$item['quantity'] . " x " . $item['name'] . "\n\n";
        }

        $request = array(
          'order_id'       =>  $order->data['id'],
          'amount'         =>  (float)currency::format_raw($order->data['payment_due'], $order->data['currency_code'], $order->data['currency_value']),
          'currency'       =>  $order->data['currency_code'],
          'auto_settle'    =>  $this->settings['auto_settle'],
          'customer_name'  => $order->data['customer']['firstname'] .' '. $order->data['customer']['lastname'],
          'customer_email' =>  $order->data['customer']['email'],
          'description'    =>  $description,
          'success_url'    =>  document::ilink('order_process'),
        );

        $result = $this->_call('POST', '/charges', $request);

        session::$data['opennode']['transaction'] = $result['id'];

        if ($this->settings['gateway'] == 'Development') {
          $url = 'https://dev-checkout.opennode.com/'.$result['id'];
        } else {
          $url = 'https://checkout.opennode.com/'.$result['id'];
        }

        return array(
          'action' => $url,
          'method' => 'GET'
        );

      } catch (Exception $e) {
        return array('error' => $e->getMessage());
      }
    }

    public function verify($order) {

      try {

        if (empty(session::$data['opennode']['transaction'])) {
          throw new Exception('No transaction detected.');
        }

        $result = $this->_call('GET', '/charge/'.session::$data['opennode']['transaction']);

        if (empty($result['status']) || !in_array($result['status'], array('paid', 'processing'))) {
          throw new Exception('The payment was not completed.');
        }

        return array(
          'order_status_id' => $this->settings['order_status_id'],
          'transaction_id' => session::$data['opennode']['transaction'],
        );

      } catch (Exception $e) {
        return array('error' => $e->getMessage());
      }
    }

    private function _call($method, $endpoint, $request=null, $headers=array()) {

      $headers = array(
        'Authorization' => $this->settings['api_key'],
        'Accept' => 'application/json',
        'Content-Type' => 'application/json; charset='. language::$selected['charset'],
      );

      if ($this->settings['gateway'] == 'Development') {
        $url = 'https://dev-api.opennode.com/v1';
      } else {
        $url = 'https://api.opennode.com/v1';
      }

      if ($method != 'GET' && !$request = json_encode($request, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)) {
        throw new Exception(json_last_error_msg());
      }

      $client = new wrap_http();
      $response = $client->call($method, $url.$endpoint, $request, $headers);

      if (!$json = json_decode($response, true)) {
        throw new Exception('Invalid JSON response: '. json_last_error_msg());
      }
      if (!in_array($client->last_response['status_code'], array(200, 201)) || !isset($json['data']['status']) || $json['data']['status'] == 'false') {
        if (!empty($json['data']['message'])) {
          throw new Exception($json['data']['message']);
        } else {
          throw new Exception('Unknown error');
        }
      }

      return $json['data'];
    }

    function settings() {
      return array(
        array(
          'key' => 'status',
          'default_value' => '0',
          'title' => 'Status',
          'description' => 'Enables or disables the module.',
          'function' => 'toggle("e/d")',
        ),
        array(
          'key' => 'icon',
          'default_value' => 'images/payment/opennode.png',
          'title' => 'Icon',
          'description' => 'Web path of the icon to be displayed.',
          'function' => 'text()',
        ),
        array(
          'key' => 'api_key',
          'default_value' => '',
          'title' => language::translate(__CLASS__.':title_api_key', 'Api Key'),
          'description' => language::translate(__CLASS__.':description_api_key', 'Payment Opennode API Authentication Token.'),
          'function' => 'text()',
        ),
        array(
          'key' => 'gateway',
          'default_value' => 'Production',
          'title' => language::translate(__CLASS__.':title_gateway', 'Gateway'),
          'description' => language::translate(__CLASS__.':description_gateway', 'Select your payment gateway.'),
          'function' => 'radio(\'Development\',\'Production\')',
        ),
        array(
          'key' => 'auto_settle',
          'default_value' => '1',
          'title' => 'Auto Settle',
          'description' => 'Convert to merchant\'s currency (needs Bank account enabled).',
          'function' => 'toggle("e/d")',
        ),
        array(
          'key' => 'currency',
          'default_value' => 'USD',
          'title' => language::translate(__CLASS__.':title_currency_code', 'Online Store Currency Code'),
          'description' => language::translate(__CLASS__.':description_currency_code', 'The currency prices in your store are shown to buyers. Example: USD'),
          'function' => 'text()',
        ),
        array(
          'key' => 'order_status_id',
          'default_value' => '',
          'title' => 'Order Status',
          'description' => 'Set the given order status upon successfully completed.',
          'function' => 'order_status()',
        ),
        array(
          'key' => 'priority',
          'default_value' => '0',
          'title' => 'Priority',
          'description' => 'Process this module in the given priority order.',
          'function' => 'int()',
        ),
      );
    }

    public function install() {
    }

    public function uninstall() {
    }
  }
