<?php
/*
 * This file contains transaction operations.
 */

/**
 * Class YooMoneyApiTransaction
 */
class YooMoneyApiTransaction extends stdClass
{
    const STATUS_IN_PROCESS = 'in_process';
    const STATUS_PROCESSED = 'processed';
    const STATUS_PAYED = 'payed';
    const STATUS_FAILED = 'failed';
    const STATUS_COMPLETED = 'completed';

    /**
     * @var int Transaction id.
     */
    public $ymid;
    /**
     * @var int Transaction user id.
     */
    public $uid;
    /**
     * @var int Transaction amount.
     */
    public $amount;
    /**
     * @var int Unix timestamp when the transaction was created.
     */
    public $created;
    /**
     * @var string Transaction status.
     */
    public $status;
    /**
     * @var string Transaction user email.
     */
    public $mail;
    /**
     * @var int Order id.
     */
    public $order_id;
    /**
     * @var array Array of additional transaction information.
     */
    public $data;

    public $payment_id;

    /**
     *
     */
    public function __construct()
    {
        $this->status = YooMoneyApiTransaction::STATUS_IN_PROCESS;
        $this->created = time();
        $this->data = array();
        $this->payment_id = '';
    }
}

/**
 * @param int $ymid Transaction id.
 * @return YooMoneyApiTransaction
 */
function yoomoney_api_transaction_load($ymid)
{
    $row = $transaction = db_select('yoomoney_api_transaction', 'yt')
        ->fields('yt')
        ->condition('yt.ymid', $ymid)
        ->execute()
        ->fetch();

    if (!$row) {
        return NULL;
    }

    $transaction = new YooMoneyApiTransaction();
    foreach ($row as $key => $value) {
        $transaction->{$key} = $value;
    }

    $transaction->data = unserialize($transaction->data);

    return $transaction;
}

/**
 * @param int $order_id Order id.
 * @return YooMoneyApiTransaction
 */
function yoomoney_api_transaction_load_by_order($order_id)
{
    $row = $transaction = db_select('yoomoney_api_transaction', 'yt')
        ->fields('yt')
        ->condition('yt.order_id', $order_id)
        ->execute()
        ->fetch();

    if (!$row) {
        return NULL;
    }

    $transaction = new YooMoneyApiTransaction();
    foreach ($row as $key => $value) {
        $transaction->{$key} = $value;
    }

    $transaction->data = unserialize($transaction->data);

    return $transaction;
}

/**
 * @param string $payment_id
 * @return YooMoneyApiTransaction
 */
function yoomoney_api_transaction_load_by_payment($payment_id)
{
    $row = $transaction = db_select('yoomoney_api_transaction', 'yt')
        ->fields('yt')
        ->condition('yt.payment_id', $payment_id)
        ->execute()
        ->fetch();

    if (!$row) {
        return NULL;
    }

    $transaction = new YooMoneyApiTransaction();
    foreach ($row as $key => $value) {
        $transaction->{$key} = $value;
    }

    $transaction->data = unserialize($transaction->data);

    return $transaction;
}

/**
 * @param YooMoneyApiTransaction $transaction
 * @return bool
 */
function yoomoney_api_transaction_save(YooMoneyApiTransaction $transaction)
{
    $fields = (array)$transaction;
    $fields['data'] = serialize($transaction->data);

    if ($transaction->ymid) {
        return !!db_update('yoomoney_api_transaction')
            ->fields($fields)
            ->condition('ymid', $transaction->ymid)
            ->execute();
    } else {
        unset($fields['ymid']);
        $id = db_insert('yoomoney_api_transaction')
            ->fields($fields)
            ->execute();

        $transaction->ymid = $id;
        return !!$id;
    }
}

/**
 * Simply set transaction payment_id.
 * @param $ymid string Transaction id
 * @param $payment_id string Payment id
 * @return bool
 */
function yoomoney_api_update_transaction_payment_id($ymid, $payment_id)
{
    return !!db_update('yoomoney_api_transaction')
        ->fields(array('payment_id' => $payment_id))
        ->condition('ymid', $ymid)
        ->execute();
}

/**
 * Simply set transaction status.
 * @param $payment_id string Transaction id in Kassa
 * @param $status string Transaction status.
 * @return bool
 */
function yoomoney_api_update_transaction_status($payment_id, $status)
{
    $kassaLog = new YooMoneyKassaLogger(variable_get('yoomoney_api_shop_id', 'null'));
    $kassaLog->sendHeka(array('payment-status.change.init'));
    $result = !!db_update('yoomoney_api_transaction')
        ->fields(array('status' => $status))
        ->condition('payment_id', $payment_id)
        ->execute();
    if ($result) {
        $kassaLog->sendHeka(array('payment-status.change.success'));
    } else {
        $kassaLog->sendHeka(array('payment-status.change.fail'));
    }
    return $result;
}

/**
 * Simply set transaction status.
 * @param $payment_id string Transaction id in Kassa
 * @param $amount
 * @return bool
 */
function yoomoney_api_update_transaction_amount($payment_id, $amount)
{
    return !!db_update('yoomoney_api_transaction')
        ->fields(array('amount' => $amount))
        ->condition('payment_id', $payment_id)
        ->execute();
}

/**
 * Delete user payment transaction
 * @param int $ymid
 * @return bool
 */
function yoomoney_api_transaction_delete($ymid)
{
    return !!db_delete('yoomoney_api_transaction')
        ->condition('ymid', $ymid)
        ->execute();
}

/**
 * Render all transactions page
 * @return mixed
 */
function yoomoney_api_transactions_page()
{
    $transactions = db_select('yoomoney_api_transaction', 'yt')
        ->fields('yt')
        ->extend('PagerDefault')// this adds the pager
        ->orderBy('ymid', 'DESC')
        ->limit(20);
    $transactions = $transactions->execute()->fetchAll();

    $table = yoomoney_api_create_transaction_table($transactions);
    $output = drupal_render($table);
    drupal_set_title(t('Transactions'));
    drupal_add_js('
        function yoomoney_api_capture_payment_request() {
            document.getElementsByTagName("body")[0].style.cursor = "wait";
            let paymentId = this.dataset.paymentId;
            let r = new XMLHttpRequest();
            let el = document.createElement("span");
            el.innerText = this.text;
            this.parentElement.insertBefore(el, this);
            this.style.display = "none";
            r.open("POST", "' . url('admin/yoomoney_api/actions') . '", true);
            r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            r.onreadystatechange = function () {
                if (r.readyState !== 4) {
                    return;
                }
                document.getElementsByTagName("body")[0].style.cursor = "default";
                if(r.status === 200 && r.responseText === "OK") { 
                    alert("' . t('Вы подтвердили платёж в ЮKassa.') . '");
                } else {
                    alert("' . t('Платёж не подтвердился. Попробуйте ещё раз.') . '");
                }
                location.reload();
            };
            r.send("action=capturePayment&paymentId=" + this.dataset.paymentId 
                    + "&module=" + this.dataset.module);    
        }
        function yoomoney_api_cancel_payment_request() {
            document.getElementsByTagName("body")[0].style.cursor = "wait";
            let paymentId = this.dataset.paymentId;
            let r = new XMLHttpRequest();
            let el = document.createElement("span");
            el.innerText = this.text;
            this.parentElement.insertBefore(el, this);
            this.style.display = "none";
            r.open("POST", "' . url('admin/yoomoney_api/actions') . '", true);
            r.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            r.onreadystatechange = function () {
                if (r.readyState !== 4) {
                    return;
                }
                document.getElementsByTagName("body")[0].style.cursor = "default";
                if(r.status === 200 && r.responseText === "OK") {
                    alert("' . t('Вы отменили платёж в ЮKassa. Деньги вернутся клиенту.') . '");
                } else {
                    alert("' . t('Платёж не отменился. Попробуйте ещё раз.') . '");
                }
                location.reload();
            };
            r.send("action=cancelPayment&paymentId=" + this.dataset.paymentId
                    + "&module=" + this.dataset.module);    
        }
        document.addEventListener("DOMContentLoaded", function() {
           [].forEach.call(document.getElementsByClassName("yoomoney_api_capture_request_link"), function(el) {
              el.addEventListener("click", yoomoney_api_capture_payment_request);
           });
           [].forEach.call(document.getElementsByClassName("yoomoney_api_cancel_request_link"), function(el) {
              el.addEventListener("click", yoomoney_api_cancel_payment_request);
           });
        });', 'inline');
    return $output;
}

/**
 * Render user transactions
 * @param stdClass $user
 * @return bool|string
 */
function yoomoney_api_transactions_user_page($user)
{
    $transactions = db_select('yoomoney_api_transaction', 'yt')
        ->fields('yt')
        ->condition('uid', $user->uid)
        ->extend('PagerDefault') // this adds the pager
        ->orderBy('ymid', 'DESC')
        ->limit(20);
    $transactions = $transactions->execute()->fetchAll();

    $table = yoomoney_api_create_transaction_table($transactions);
    $output = drupal_render($table);
    drupal_set_title(t('My transactions'));
    return $output;
}


/**
 * @param array $table_rows
 * @return array
 */
function yoomoney_api_create_transaction_table($table_rows)
{
    $rows = array();
    if (count($table_rows) > 0) {
        foreach ($table_rows as $item) {
            $row = yoomoney_api_transaction_build_payment_row((array)$item);
            $orderId = $row['order_id'];
            $actions = '';
            $module = '';
            if (module_exists('commerce')
                && commerce_order_load($row['order_id'])
                && yooCommerceApiPaymentTransactioLoad($row['payment_id'])
            ) {
                $module = 'commerce';
                $row['order_id'] = l($row['order_id'], 'admin/commerce/orders/' . $orderId);
                $actions .= l(t('View'), 'admin/commerce/orders/' . $orderId) . ' ';
            } elseif (module_exists('uc_payment')
                && uc_order_load($row['order_id'])
            ) {
                $module = 'uc_payment';
                $row['order_id'] = l($row['order_id'], 'admin/store/orders/' . $orderId);
                $actions .= l(t('View'), 'admin/store/orders/' . $orderId) . ' ';
            }
            if ($row['status'] === \YooKassa\Model\PaymentStatus::WAITING_FOR_CAPTURE) {
                if ($module) {
                    if ($module === 'commerce') {
                        $actions .= l(t('Edit'), 'admin/commerce/orders/' . $orderId . '/edit');
                    } elseif ($module === 'uc_payment') {
                        $actions .= l(t('Edit'), 'admin/store/orders/' . $orderId . '/edit');
                    }
                    $actions .= ' <a href="javascript:void(0);" class="yoomoney_api_capture_request_link" data-payment-id="' . $row['payment_id'] . '" data-module="' . $module . '">' . t('Confirm') . '</a> ';
                    $actions .= '<a href="javascript:void(0);" class="yoomoney_api_cancel_request_link" data-payment-id="' . $row['payment_id'] . '" data-module="' . $module . '">' . t('Cancel') . '</a>';
                }
            }
            $row[] = $actions;
            $rows[] = $row;
        }
        $header = array(t('Id'), t('Name'), t('Amount'), t('Date/Time'), t('Status'), t('E-mail'), t('Order ID'), t('Payment ID'), t('Actions'));
        $table['table_rows'] = array(
            '#theme' => 'table',
            '#rows' => $rows,
            '#header' => $header,
        );

        $table['pager'] = array(
            '#theme' => 'pager',
            '#weight' => 5,
        );
    } else {
        $table = array(
            '#type' => 'markup',
            '#markup' => t('There no transactions.'),
        );
    }
    return $table;
}

/**
 * @param array $row
 * @return array
 */
function yoomoney_api_transaction_build_payment_row($row)
{
    unset($row['data']);
    foreach ($row as $key => $item) {
        if ($key == 'uid') {
            if ($item) {
                $user = user_load($item);
                $item = $user->name;
            } else {
                $item = 'guest';
            }
        }
        if ($key == 'created') {
            $item = format_date($item, 'custom', 'd-m-Y H:i:s');
        }
        if ($key == 'amount') {
            $item = $item . ' RUR';
        }
        $row[$key] = $item;
    }
    return $row;
}
