<?php

defined('BASEPATH') OR exit('No direct script access allowed');
/**
 * Pancake
 * A simple, fast, self-hosted invoicing application
 *
 * @package             Pancake
 * @author              Pancake Dev Team
 * @copyright           Copyright (c) 2010, Pancake Payments
 * @license             http://pancakeapp.com/license
 * @link                http://pancakeapp.com
 * @since               Version 3.2.6
 */
// ------------------------------------------------------------------------

/**
 * The Stripe Gateway
 *
 * @subpackage    Gateway
 * @category      Payments
 */
class Stripe_m extends Gateway {

    public $requires_https = true;
    public $requires_pci = false;

    function __construct() {
        parent::__construct(__CLASS__);
        $this->title = 'Stripe';
        $this->frontend_title = __('paypalpro:viacreditcard');
        $this->use_field_names = false;
        $publishable_key = $this->get_field('publishable_key');
        $this->custom_head = <<<stuff
<script type="text/javascript" src="https://js.stripe.com/v1/"></script><script type="text/javascript">Stripe.setPublishableKey('$publishable_key');
$(function() {
  $('#payment-form').submit(function(event) {
    // Disable the submit button to prevent repeated clicks
    $('.submit-button').prop('disabled', true);

    Stripe.createToken({
	  name: $('#cc_name').val(),
      number: $('#cc_number').val(),
      cvc: $('#cc_code').val(),
      exp_month: $('#cc_exp_m').val(),
      exp_year: $('#cc_exp_y').val()
    }, stripeResponseHandler);

    // Prevent the form from submitting with the default action
    return false;
  });
});      

function stripeResponseHandler(status, response) {
  if (response.error) {
    // Show the errors on the form
    $('.errors').text(response.error.message);
    $('.submit-button').prop('disabled', false);
  } else {
    var \$form = $('#payment-form');
    // token contains id, last4, and card type
    var token = response.id;
    // Insert the token into the form so it gets submitted to the server
    \$form.append($('<input type="hidden" name="client_fields[stripe_token]" />').val(token));
    // and submit
    \$form[0].submit();
  }
}

</script>
stuff;

        if (!defined('GATEWAY_API_KEY')) {
            define('GATEWAY_API_KEY', $this->get_field('publishable_key'));
        }

        $this->fields = array(
            'api_key' => "Stripe Secret Key",
            'publishable_key' => "Stripe Publishable Key",
        );

        $this->client_fields = array(
            'cc_name' => array(
                'label' => __('gateways:cc_cardholder'),
            ),
            'cc_number' => array(
                'label' => __('gateways:cc_number'),
            ),
            'cc_code' => array(
                'label' => __('gateways:cc_code'),
            ),
            'cc_exp' => array(
                'type' => 'mmyyyy',
                'label' => __('gateways:cc_exp'),
            ),
        );
    }

    public function setup_stripe() {
        \Stripe\Stripe::setApiKey($this->get_field('api_key'));
        $this->load->config("stripe");
        $curlopts = $this->config->item('stripe_curlopts');
        $curl = new \Stripe\HttpClient\CurlClient($curlopts);
        \Stripe\ApiRequestor::setHttpClient($curl);
        \Stripe\Stripe::setAppInfo("Pancake", Settings::get('version'), "https://www.pancakeapp.com");
    }

    public function create_charge($client_id, $item_name, $amount, $currency_code) {
        $this->setup_stripe();

        $token = $this->get_token($client_id, $amount, $currency_code);
        if ($token) {
            try {
                $charge = \Stripe\Charge::create(array(
                    "amount" => $amount * 100,
                    "currency" => strtolower($currency_code),
                    "customer" => $token,
                    "description" => $item_name,
                ));
            } catch (\Stripe\Error\Card $e) {
                $this->unset_token($client_id);
                $this->error($e->getMessage());
                return false;
            }

            if ($charge->paid) {
                $balance_transaction = \Stripe\BalanceTransaction::retrieve($charge->balance_transaction);
                $transaction_fee = $balance_transaction->fee / 100;

                return array(
                    'txn_id' => $charge->id, // the gateway transaction ID
                    'payment_gross' => $amount, // the amount paid, rounded to 2 decimal places
                    'transaction_fee' => $transaction_fee, // the fee charged by the gateway, rounded to 2 decimal places
                    'payment_date' => $charge->created, // a UNIX timestamp for the payment date
                    'payment_status' => 'Completed', // One of: Completed/Pending/Refunded/Unpaid
                    'item_name' => $item_name, // the item name (passed to the gateway in generate_payment_form())
                    'is_paid' => true, // true or false, depending on whether payment was successful or not
                );
            } else {
                $this->unset_token($client_id);
                $this->error("Error {$charge->failure_code}: {$charge->failure_message}");
                return false;
            }
        } else {
            return false;
        }
    }

    public function generate_payment_form($unique_id, $item_name, $amount, $success, $cancel, $notify, $currency_code, $invoice_number) {
        $this->setup_stripe();

        $invoice_id = $this->ppm->getUniqueInvoiceIdByUniqueId($unique_id);
        $client_id = $this->invoice_m->getClientIdByUniqueId($invoice_id);
        $client = $this->clients_m->getById($client_id);

        try {
            $customer = \Stripe\Customer::create(array(
                "description" => client_name($client_id),
                "email" => $client["email"],
                "source" => $this->get_client_field('stripe_token'),
            ));
        } catch (\Stripe\Error\Card $e) {
            $this->error($e->getMessage());
            return false;
        }

        $expiry_date = carbon("{$customer->sources->data[0]->exp_year}-{$customer->sources->data[0]->exp_month}-01");
        $this->set_token($client_id, $customer->id, $expiry_date);

        return $this->create_charge($client_id, $item_name, $amount, $currency_code);
    }
}